# Copyright (c) 2025 Huawei Technologies Co., Ltd.
# openUBMC is licensed under Mulan PSL v2.
# You can use this software according to the terms and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
#         http://license.coscl.org.cn/MulanPSL2
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
# See the Mulan PSL v2 for more details.

"""
异步数据流分析

负责分析异步函数的 Segment 和 Unit 划分，以及变量提升分析。

核心概念：
1. Segment（段）：在当前语句块层次，按 await 分割的代码段，有父子关系
2. Unit（最小代码单元）：按 await 分割的最小代码块，无父子关系
3. 变量提升：基于 Segment 父子关系判断变量是否跨 await
"""

from dataclasses import dataclass, field
from typing import List, Dict, Optional, Tuple

from mcpy.ir.base import IRNode
from mcpy.ir.statements import (
    IRStmtBlock,
    IRIf,
    IRForRange,
    IRForEach,
    IRWhile,
    IRTryExcept,
    IRAssign,
)
from mcpy.ir.statements.control import IRReturn
from mcpy.ir.declarations.function import IRFunctionNode
from mcpy.ir.expressions.comprehension import IRListComp, IRComprehension
from mcpy.ir.expressions.await_expr import IRAwait
from mcpy.ir.expressions.call import IRCall
from mcpy.ir.expressions.basic import IRName
from mcpy.symbol_meta import Symbol, TypeInfo, SymbolKind


@dataclass
class Segment:
    """代码段（Segment）

    在当前语句块层次，按 await 语句分割的代码段。
    包含 await 的子语句块会成为 Segment 的分割点。

    特点：
    - 有父子关系（parent_segment_id）
    - 可以包含子语句块
    - 用于判断变量是否跨 await
    """

    segment_id: int
    start_stmt_index: int
    end_stmt_index: int  # 不包含
    has_await: bool
    contains_sub_blocks: bool
    statement_block_node: IRNode  # 所属的语句块节点
    parent_segment_id: Optional[int] = None  # 父 Segment ID
    try_block_id: Optional[int] = None  # 所属的 try 块 ID（如果 Segment 在 try 块内）
    try_block_depth: int = 0  # try 块嵌套深度
    parent_try_block_id: Optional[int] = None  # 父 try 块 ID（用于嵌套 try 块）


@dataclass
class Unit:
    """最小代码单元（Unit）

    在同一语句块层次，按 await 语句分割的最小代码段。
    不跨越语句块边界，用于变量提升分析。

    特点：
    - 无父子关系
    - 不包含子语句块
    - 用于判断局部变量作用域
    """

    unit_id: int
    start_stmt_index: int
    end_stmt_index: int  # 不包含
    has_await: bool  # 此单元是否包含 await 表达式的执行
    statement_block_node: IRNode  # 所属的语句块节点
    segment_id: int  # 所属的 Segment ID
    variables_defined: List[str] = field(default_factory=list)  # 在此单元定义的变量
    try_block_id: Optional[int] = None  # 所属的 try 块 ID（如果 Unit 在 try 块内）
    try_block_depth: int = 0  # try 块嵌套深度
    parent_try_block_id: Optional[int] = None  # 父 try 块 ID（用于嵌套 try 块）


@dataclass
class VariablePromotionInfo:
    """变量提升信息"""

    variable_name: str
    promotion_type: str  # "member", "header", "local"
    reason: str  # 提升原因
    defined_in_unit_id: Optional[int] = None  # 定义所在的 Unit ID
    defined_in_segment_id: Optional[int] = None  # 定义所在的 Segment ID
    used_in_unit_ids: List[int] = field(default_factory=list)  # 使用所在的 Unit ID 列表
    used_in_segment_ids: List[int] = field(
        default_factory=list
    )  # 使用所在的 Segment ID 列表

    # 新增：完整的类型和符号信息
    ir_node: Optional[IRNode] = None  # 变量定义的 IR 节点（如 IRAssign 的 target）
    symbol: Optional["Symbol"] = None  # 符号表中的符号对象
    type_info: Optional["TypeInfo"] = None  # TypeInfo 对象（Python 类型）
    init_expr: Optional[IRNode] = (
        None  # 变量的初始化表达式（用于 Protocol 类型的 decltype）
    )

    # 新增：捕获变量分类信息
    is_captured_variable: bool = False  # 是否是捕获的闭包变量
    is_local_member: bool = False  # 是否是局部成员变量（在函数内部定义）
    captured_from_scope: Optional[str] = None  # 捕获自哪个作用域（外层函数名）


@dataclass
class TryBlockInfo:
    """try 块信息（用于代码生成）"""

    try_block_id: int
    try_node: IRTryExcept  # try 块节点（保留用于向后兼容）
    parent_try_block_id: Optional[int] = None  # 父 try 块 ID
    depth: int = 0  # 嵌套深度
    
    # 结构信息（从 try_node 中提取）
    has_finally: bool = False  # 是否有 finally 块
    has_else: bool = False  # 是否有 else 块
    has_except_handlers: bool = False  # 是否有 except 处理器
    
    # 上下文信息（在数据流分析时收集）
    in_loop: bool = False  # 是否在循环中（for/while）
    loop_type: Optional[str] = None  # 循环类型："for" 或 "while"


@dataclass
class AsyncDataFlowInfo:
    """异步函数的数据流信息"""

    segments: List[Segment] = field(default_factory=list)
    units: List[Unit] = field(default_factory=list)
    variable_promotions: Dict[str, VariablePromotionInfo] = field(default_factory=dict)
    try_blocks: List[TryBlockInfo] = field(default_factory=list)  # try 块列表

    # 用于代码生成（向后兼容）
    member_variables: List[str] = field(default_factory=list)
    header_variables: List[str] = field(default_factory=list)
    local_variables: Dict[int, List[str]] = field(default_factory=dict)


class AsyncDataFlowAnalyzer:
    """异步数据流分析器

    负责：
    1. Segment 划分（有父子关系）
    2. Unit 划分（无父子关系）
    3. 变量提升分析（基于 Segment 父子关系）
    """

    def __init__(self) -> None:
        self.segment_id_counter: int = 0
        self.unit_id_counter: int = 0

    def _is_type_name(self, name_node: IRName) -> bool:
        """判断 IRName 是否是类型名称（不应该被识别为变量）

        以下情况应该被识别为类型名称：
        1. IRName 是 IRSubscript 的一部分（如 list[int] 中的 list 和 int），
           且该 IRSubscript 是 IRCall 的 func（类型构造函数调用）
        2. IRName 是 IRCall 的 func，且该 IRCall 是类型构造函数调用（如 int()）

        Args:
            name_node: IRName 节点

        Returns:
            True 表示是类型名称，不应该被识别为变量
        """
        from mcpy.ir.expressions.access import IRSubscript
        from mcpy.symbol_meta import SymbolKind

        parent = name_node.parent
        if parent is None:
            return False

        # 情况1: IRName 是 IRSubscript 的一部分（如 list[int] 中的 list 和 int）
        if isinstance(parent, IRSubscript):
            # 检查 IRSubscript 是否是 IRCall 的 func（类型构造函数调用）
            subscript_parent = parent.parent
            if isinstance(subscript_parent, IRCall):
                # list[int]() 这种类型构造函数调用
                if subscript_parent.func == parent:
                    return True

        # 情况2: IRName 本身是 IRCall 的 func（如 int()）
        if isinstance(parent, IRCall) and parent.func == name_node:
            # 检查是否是类型构造函数调用
            # 通过符号查找判断是否是类型符号
            try:
                symbol = name_node.lookup_symbol(
                    name_node.id, symbol_kinds=[SymbolKind.CLASS]
                )
                if symbol and symbol.kind == SymbolKind.CLASS:
                    # 是类型符号，且是函数调用的 func，说明是类型构造函数调用
                    return True
            except Exception:
                # 符号查找可能失败，忽略
                pass

        return False

    def analyze(self, func_node: IRNode) -> AsyncDataFlowInfo:
        """分析异步函数的数据流

        Args:
            func_node: 函数节点

        Returns:
            AsyncDataFlowInfo: 数据流信息
        """
        info = AsyncDataFlowInfo()

        # 获取函数体
        if not isinstance(func_node, IRFunctionNode) or not func_node.body:
            return info

        # 1. 划分 Segments（有父子关系）
        self._analyze_segments(
            func_node.body, info, parent_segment_id=None, try_block_stack=[], loop_stack=[]
        )

        # 2. 划分 Units（无父子关系）
        # 找到函数体对应的第一个 Segment ID
        root_segment_id = self._find_segment_for_block(
            info, func_node.body, fallback_segment_id=None
        )
        self._analyze_units(func_node.body, info, root_segment_id, try_block_stack=[], loop_stack=[])

        # 3. 变量提升分析
        self._analyze_variable_promotions(func_node, info)

        # 4. 验证和补充 captured_vars（确保包含所有捕获变量）
        if isinstance(func_node, IRFunctionNode):
            self._validate_and_supplement_captured_vars(func_node, info)

        return info

    def _analyze_segments(
        self,
        statement_block: IRNode,
        info: AsyncDataFlowInfo,
        parent_segment_id: Optional[int],
        try_block_stack: Optional[List[int]] = None,
        loop_stack: Optional[List[str]] = None,
    ) -> None:
        """递归分析 Segments

        Segment 划分规则：
        1. 在同一语句块层次，按 await 语句分段
        2. 遇到包含 await 的子语句块（if/for/while）时，子语句块成为分割点
        3. try 块不分割 Segment，但需要记录 try 块信息
        4. 子语句块内部递归应用相同规则

        Args:
            statement_block: 语句块节点
            info: 数据流信息
            parent_segment_id: 父 Segment ID
            try_block_stack: 当前 try 块栈（try_block_id 列表）
            loop_stack: 当前循环栈（循环类型列表："for" 或 "while"）
        """
        if try_block_stack is None:
            try_block_stack = []
        if loop_stack is None:
            loop_stack = []

        statements = getattr(statement_block, "statements", [])
        if not statements:
            return

        current_segment_start = 0
        i = 0

        while i < len(statements):
            stmt = statements[i]

            # 情况1：当前语句是 await 赋值
            if isinstance(stmt, IRAssign) and isinstance(stmt.value, IRAwait):
                # 当前 Segment 结束（包含这个 await）
                segment = Segment(
                    segment_id=self.segment_id_counter,
                    start_stmt_index=current_segment_start,
                    end_stmt_index=i + 1,
                    has_await=True,
                    contains_sub_blocks=False,
                    statement_block_node=statement_block,
                    parent_segment_id=parent_segment_id,
                    try_block_id=try_block_stack[-1] if try_block_stack else None,
                    try_block_depth=len(try_block_stack),
                    parent_try_block_id=(
                        try_block_stack[-2] if len(try_block_stack) > 1 else None
                    ),
                )
                info.segments.append(segment)
                self.segment_id_counter += 1

                # 下一个 Segment 从下一个语句开始
                current_segment_start = i + 1
                i += 1

            # 情况2：当前语句是 try 块
            elif isinstance(stmt, IRTryExcept):
                # try 块不分割 Segment，但需要记录 try 块信息
                # 检查 try 块是否包含 await（用于创建 try 块信息）
                has_await = self._check_sub_blocks_have_await(stmt)

                if has_await:
                    # 创建 try 块信息
                    try_block_id = len(info.try_blocks)
                    try_block_info = TryBlockInfo(
                        try_block_id=try_block_id,
                        try_node=stmt,
                        parent_try_block_id=(
                            try_block_stack[-1] if try_block_stack else None
                        ),
                        depth=len(try_block_stack),
                        # 从 try_node 中提取结构信息
                        has_finally=bool(stmt.finalbody),
                        has_else=bool(stmt.orelse),
                        has_except_handlers=bool(stmt.handlers),
                        # 从循环栈中获取上下文信息
                        in_loop=len(loop_stack) > 0,
                        loop_type=loop_stack[-1] if loop_stack else None,
                    )
                    info.try_blocks.append(try_block_info)

                    # 递归进入 try 块（push try_block_id 到栈）
                    new_try_block_stack = try_block_stack + [try_block_id]
                    self._recurse_into_try_blocks(
                        stmt, info, parent_segment_id, new_try_block_stack, loop_stack
                    )
                else:
                    # try 块不包含 await，仍然需要记录 try 块信息（用于异常处理）
                    try_block_id = len(info.try_blocks)
                    try_block_info = TryBlockInfo(
                        try_block_id=try_block_id,
                        try_node=stmt,
                        parent_try_block_id=(
                            try_block_stack[-1] if try_block_stack else None
                        ),
                        depth=len(try_block_stack),
                        has_finally=bool(stmt.finalbody),
                        has_else=bool(stmt.orelse),
                        has_except_handlers=bool(stmt.handlers),
                        # 从循环栈中获取上下文信息
                        in_loop=len(loop_stack) > 0,
                        loop_type=loop_stack[-1] if loop_stack else None,
                    )
                    info.try_blocks.append(try_block_info)

                    # 递归进入 try 块（push try_block_id 到栈）
                    new_try_block_stack = try_block_stack + [try_block_id]
                    self._recurse_into_try_blocks(
                        stmt, info, parent_segment_id, new_try_block_stack, loop_stack
                    )

                i += 1

            # 情况3：当前语句是其他控制流语句块（if/for/while）
            elif isinstance(stmt, (IRIf, IRForRange, IRForEach, IRWhile)):
                # 检查子语句块是否包含 await
                sub_block_has_await = self._check_sub_blocks_have_await(stmt)

                if sub_block_has_await:
                    # 子语句块包含 await，当前 Segment 结束（包含这个控制流语句）
                    sub_segment_id = self.segment_id_counter
                    segment = Segment(
                        segment_id=sub_segment_id,
                        start_stmt_index=current_segment_start,
                        end_stmt_index=i + 1,  # 包含控制流语句
                        has_await=True,
                        contains_sub_blocks=True,
                        statement_block_node=statement_block,
                        parent_segment_id=parent_segment_id,
                        try_block_id=try_block_stack[-1] if try_block_stack else None,
                        try_block_depth=len(try_block_stack),
                        parent_try_block_id=(
                            try_block_stack[-2] if len(try_block_stack) > 1 else None
                        ),
                    )
                    info.segments.append(segment)
                    self.segment_id_counter += 1

                    # 递归进入子语句块，parent_segment_id 设置为当前 Segment
                    self._recurse_into_sub_blocks(
                        stmt, info, sub_segment_id, try_block_stack, loop_stack
                    )

                    # 下一个 Segment 从下一个语句开始
                    current_segment_start = i + 1
                else:
                    # 子语句块不包含 await，继续累积到当前 Segment
                    pass

                i += 1

            else:
                # 普通语句，继续累积
                i += 1

        # 处理剩余的语句（最后一个 Segment）
        if current_segment_start < len(statements):
            segment = Segment(
                segment_id=self.segment_id_counter,
                start_stmt_index=current_segment_start,
                end_stmt_index=len(statements),
                has_await=False,
                contains_sub_blocks=False,
                statement_block_node=statement_block,
                parent_segment_id=parent_segment_id,
                try_block_id=try_block_stack[-1] if try_block_stack else None,
                try_block_depth=len(try_block_stack),
                parent_try_block_id=(
                    try_block_stack[-2] if len(try_block_stack) > 1 else None
                ),
            )
            info.segments.append(segment)
            self.segment_id_counter += 1

    def _check_sub_blocks_have_await(self, stmt: IRNode) -> bool:
        """检查控制流语句的子语句块是否包含 await

        Args:
            stmt: 控制流语句节点

        Returns:
            bool: 是否包含 await
        """
        if isinstance(stmt, IRIf):
            # 检查 then 分支
            if stmt.then_body and self._block_contains_await(stmt.then_body):
                return True
            # 检查 else 分支
            if stmt.else_body and self._block_contains_await(stmt.else_body):
                return True
            return False

        elif isinstance(stmt, (IRForRange, IRForEach, IRWhile)):
            # 检查循环体
            if stmt.body and self._block_contains_await(stmt.body):
                return True
            return False

        elif isinstance(stmt, IRTryExcept):
            # 检查 try 块 (body)
            if stmt.body and self._block_contains_await(stmt.body):
                return True
            # 检查 except 处理器 (handlers)
            if stmt.handlers:
                for handler in stmt.handlers:
                    if handler.body and self._block_contains_await(handler.body):
                        return True
            # 检查 finally 块 (finalbody)
            if stmt.finalbody and self._block_contains_await(stmt.finalbody):
                return True
            return False

        return False

    def _block_contains_await(self, block: IRNode) -> bool:
        """递归检查语句块是否包含 await

        Args:
            block: 语句块节点

        Returns:
            bool: 是否包含 await
        """
        # 遍历所有子节点
        for child in block.get_child_nodes():
            if isinstance(child, IRAwait):
                return True
            # 递归检查子节点
            if self._node_contains_await(child):
                return True

        return False

    def _node_contains_await(self, node: IRNode) -> bool:
        """递归检查节点是否包含 await

        Args:
            node: IR 节点

        Returns:
            bool: 是否包含 await
        """
        if isinstance(node, IRAwait):
            return True

        # 递归检查子节点
        for child in node.get_child_nodes():
            if self._node_contains_await(child):
                return True

        return False

    def _recurse_into_sub_blocks(
        self,
        stmt: IRNode,
        info: AsyncDataFlowInfo,
        parent_segment_id: int,
        try_block_stack: Optional[List[int]] = None,
        loop_stack: Optional[List[str]] = None,
    ) -> None:
        """递归进入子语句块进行 Segment 划分

        Args:
            stmt: 控制流语句节点（if/for/while，不包括 try）
            info: 数据流信息
            parent_segment_id: 父 Segment ID
            try_block_stack: 当前 try 块栈（try_block_id 列表）
            loop_stack: 当前循环栈（循环类型列表："for" 或 "while"）
        """
        if try_block_stack is None:
            try_block_stack = []
        if loop_stack is None:
            loop_stack = []

        if isinstance(stmt, IRIf):
            # 递归处理 then 分支
            if stmt.then_body:
                self._analyze_segments(
                    stmt.then_body, info, parent_segment_id, try_block_stack, loop_stack
                )
            # 递归处理 else 分支
            if stmt.else_body:
                self._analyze_segments(
                    stmt.else_body, info, parent_segment_id, try_block_stack, loop_stack
                )

        elif isinstance(stmt, (IRForRange, IRForEach, IRWhile)):
            # 确定循环类型
            loop_type = "for" if isinstance(stmt, (IRForRange, IRForEach)) else "while"
            new_loop_stack = loop_stack + [loop_type]
            
            # 递归处理循环体（使用新的 loop_stack）
            if stmt.body:
                self._analyze_segments(
                    stmt.body, info, parent_segment_id, try_block_stack, new_loop_stack
                )

    def _recurse_into_try_blocks(
        self,
        stmt: IRTryExcept,
        info: AsyncDataFlowInfo,
        parent_segment_id: Optional[int],
        try_block_stack: List[int],
        loop_stack: Optional[List[str]] = None,
    ) -> None:
        """递归进入 try 块进行 Segment 划分

        Args:
            stmt: try 块节点
            info: 数据流信息
            parent_segment_id: 父 Segment ID
            try_block_stack: 当前 try 块栈（try_block_id 列表）
            loop_stack: 当前循环栈（循环类型列表："for" 或 "while"）
        """
        if loop_stack is None:
            loop_stack = []
        
        # 递归处理 try 块
        if stmt.body:
            self._analyze_segments(stmt.body, info, parent_segment_id, try_block_stack, loop_stack)
        # 递归处理 except 处理器
        if stmt.handlers:
            for handler in stmt.handlers:
                if handler.body:
                    self._analyze_segments(
                        handler.body, info, parent_segment_id, try_block_stack, loop_stack
                    )
        # 递归处理 else 块（如果有）
        if stmt.orelse:
            self._analyze_segments(
                stmt.orelse, info, parent_segment_id, try_block_stack, loop_stack
            )
        # 递归处理 finally 块
        if stmt.finalbody:
            self._analyze_segments(
                stmt.finalbody, info, parent_segment_id, try_block_stack, loop_stack
            )

    def _analyze_units(
        self,
        statement_block: IRNode,
        info: AsyncDataFlowInfo,
        current_segment_id: Optional[int] = None,
        try_block_stack: Optional[List[int]] = None,
        loop_stack: Optional[List[str]] = None,
    ) -> None:
        """递归分析 Units

        Unit 划分规则：
        1. 在同一语句块层次，按 await 语句分段
        2. Unit 无父子关系，但记录所属的 segment_id
        3. 递归进入子语句块时，传递对应的 segment_id
        4. try 块边界不分割 Unit，但需要记录 try 块信息

        Args:
            statement_block: 语句块节点
            info: 数据流信息
            current_segment_id: 当前所属的 Segment ID
            try_block_stack: 当前 try 块栈（try_block_id 列表）
            loop_stack: 当前循环栈（循环类型列表："for" 或 "while"）
        """
        if try_block_stack is None:
            try_block_stack = []
        if loop_stack is None:
            loop_stack = []

        statements = getattr(statement_block, "statements", [])
        if not statements:
            return

        current_unit_start = 0
        pending_await_results = []  # 待处理的 await 结果变量
        i = 0

        while i < len(statements):
            stmt = statements[i]

            # 情况1：当前语句是 await 赋值
            if isinstance(stmt, IRAssign) and isinstance(stmt.value, IRAwait):
                # 当前 Unit 结束（包含这个 await 表达式）
                unit_id = self.unit_id_counter
                self.unit_id_counter += 1

                # 收集此单元中定义的变量
                variables_defined = (
                    pending_await_results
                    + self._collect_variables_defined_in_range(
                        statements, current_unit_start, i, exclude_await_results=True
                    )
                )

                unit = Unit(
                    unit_id=unit_id,
                    start_stmt_index=current_unit_start,
                    end_stmt_index=i + 1,
                    has_await=True,
                    statement_block_node=statement_block,
                    segment_id=(
                        current_segment_id if current_segment_id is not None else -1
                    ),
                    variables_defined=variables_defined,
                    try_block_id=try_block_stack[-1] if try_block_stack else None,
                    try_block_depth=len(try_block_stack),
                    parent_try_block_id=(
                        try_block_stack[-2] if len(try_block_stack) > 1 else None
                    ),
                )
                info.units.append(unit)

                # 收集当前 await 结果变量
                target = stmt.get_target_expr()
                is_declaration = stmt.get_extension_param(
                    "is_variable_declaration", True
                )
                if isinstance(target, IRName) and is_declaration:
                    pending_await_results = [target.id]
                else:
                    pending_await_results = []

                # 下一个 Unit 从下一个语句开始
                current_unit_start = i + 1
                i += 1

            # 情况2：当前语句是 try 块
            elif isinstance(stmt, IRTryExcept):
                # try 块不分割 Unit，但需要记录 try 块信息
                # 找到对应的 try_block_id
                try_block_id = None
                for try_block_info in info.try_blocks:
                    if try_block_info.try_node == stmt:
                        try_block_id = try_block_info.try_block_id
                        break

                if try_block_id is not None:
                    # 递归进入 try 块（push try_block_id 到栈）
                    new_try_block_stack = try_block_stack + [try_block_id]
                    # 需要找到 try 块对应的 segment_id
                    sub_segment_id = self._find_segment_for_statement(
                        info, statement_block, i
                    )
                    if sub_segment_id is None:
                        sub_segment_id = current_segment_id
                    self._recurse_into_try_blocks_for_units(
                        stmt, info, sub_segment_id, new_try_block_stack, loop_stack
                    )

                i += 1

            # 情况2.5：当前语句是 return await
            # 注意：理论上这段代码不再需要，因为 AwaitTransformPass 会在更早期将 return await
            # 拆分为 __tmp = await ...; return __tmp 两个语句。但保留作为防御性代码，
            # 以防万一有其他地方直接创建了 return await 的 IR。
            elif (
                isinstance(stmt, IRReturn)
                and stmt.expr
                and isinstance(stmt.expr, IRAwait)
            ):
                # return await 语句：需要创建一个包含 await 的 Unit
                unit_id = self.unit_id_counter
                self.unit_id_counter += 1

                # 收集此单元中定义的变量
                variables_defined = (
                    pending_await_results
                    + self._collect_variables_defined_in_range(
                        statements, current_unit_start, i, exclude_await_results=True
                    )
                )

                unit = Unit(
                    unit_id=unit_id,
                    start_stmt_index=current_unit_start,
                    end_stmt_index=i + 1,
                    has_await=True,
                    statement_block_node=statement_block,
                    segment_id=(
                        current_segment_id if current_segment_id is not None else -1
                    ),
                    variables_defined=variables_defined,
                    try_block_id=try_block_stack[-1] if try_block_stack else None,
                    try_block_depth=len(try_block_stack),
                    parent_try_block_id=(
                        try_block_stack[-2] if len(try_block_stack) > 1 else None
                    ),
                )
                info.units.append(unit)

                # return await 语句后没有后续语句，清空 pending_await_results
                pending_await_results = []
                current_unit_start = i + 1
                i += 1

            # 情况3：当前语句是其他控制流语句块（if/for/while）
            elif isinstance(stmt, (IRIf, IRForRange, IRForEach, IRWhile)):
                # 检查子语句块是否包含 await
                sub_block_has_await = self._check_sub_blocks_have_await(stmt)

                # 只有包含 await 的控制流语句才需要中断 Unit
                # 不包含 await 的控制流语句应该像普通语句一样，不中断 Unit
                if sub_block_has_await:
                    # 如果子语句块包含 await，需要在此处创建一个 Unit
                    if current_unit_start < i or pending_await_results:
                        unit_id = self.unit_id_counter
                        self.unit_id_counter += 1

                        variables_defined = (
                            pending_await_results
                            + self._collect_variables_defined_in_range(
                                statements, current_unit_start, i
                            )
                        )

                        unit = Unit(
                            unit_id=unit_id,
                            start_stmt_index=current_unit_start,
                            end_stmt_index=i,  # 不包含控制流语句
                            has_await=False,
                            statement_block_node=statement_block,
                            segment_id=(
                                current_segment_id
                                if current_segment_id is not None
                                else -1
                            ),
                            variables_defined=variables_defined,
                            try_block_id=(
                                try_block_stack[-1] if try_block_stack else None
                            ),
                            try_block_depth=len(try_block_stack),
                            parent_try_block_id=(
                                try_block_stack[-2] if len(try_block_stack) > 1 else None
                            ),
                        )
                        info.units.append(unit)

                        pending_await_results = []
                        current_unit_start = i + 1

                    # 递归进入子语句块
                    # 需要找到子语句块对应的 segment_id
                    sub_segment_id = self._find_segment_for_statement(
                        info, statement_block, i
                    )
                    if sub_segment_id is None:
                        sub_segment_id = current_segment_id
                    self._recurse_into_sub_blocks_for_units(
                        stmt, info, sub_segment_id, try_block_stack, loop_stack
                    )
                else:
                    # 不包含 await 的控制流语句，不中断 Unit，也不递归进入子语句块创建 Unit
                    # 因为不包含 await 的子语句块中的变量使用应该归入当前 Unit
                    # 循环变量只在循环体内使用，不会跨 await，所以不需要提升
                    pass

                i += 1

            # 情况4：普通语句
            else:
                i += 1

        # 处理最后一个 Unit
        if current_unit_start < len(statements) or pending_await_results:
            unit_id = self.unit_id_counter
            self.unit_id_counter += 1

            variables_defined = (
                pending_await_results
                + self._collect_variables_defined_in_range(
                    statements, current_unit_start, len(statements)
                )
            )

            unit = Unit(
                unit_id=unit_id,
                start_stmt_index=current_unit_start,
                end_stmt_index=len(statements),
                has_await=False,
                statement_block_node=statement_block,
                segment_id=current_segment_id if current_segment_id is not None else -1,
                variables_defined=variables_defined,
                try_block_id=try_block_stack[-1] if try_block_stack else None,
                try_block_depth=len(try_block_stack),
                parent_try_block_id=(
                    try_block_stack[-2] if len(try_block_stack) > 1 else None
                ),
            )
            info.units.append(unit)

    def _find_segment_for_statement(
        self, info: AsyncDataFlowInfo, statement_block: IRNode, stmt_index: int
    ) -> Optional[int]:
        """查找语句所属的 Segment ID

        Args:
            info: 数据流信息
            statement_block: 语句块节点
            stmt_index: 语句索引

        Returns:
            Segment ID，如果未找到返回 None
        """
        for segment in info.segments:
            if (
                segment.statement_block_node == statement_block
                and segment.start_stmt_index <= stmt_index < segment.end_stmt_index
            ):
                return segment.segment_id
        return None

    def _recurse_into_sub_blocks_for_units(
        self,
        stmt: IRNode,
        info: AsyncDataFlowInfo,
        parent_segment_id: Optional[int],
        try_block_stack: Optional[List[int]] = None,
        loop_stack: Optional[List[str]] = None,
    ) -> None:
        """递归进入子语句块进行 Unit 划分

        Args:
            stmt: 控制流语句节点（if/for/while，不包括 try）
            info: 数据流信息
            parent_segment_id: 父 Segment ID
            try_block_stack: 当前 try 块栈（try_block_id 列表）
            loop_stack: 当前循环栈（循环类型列表："for" 或 "while"）
        """
        if try_block_stack is None:
            try_block_stack = []
        if loop_stack is None:
            loop_stack = []

        if isinstance(stmt, IRIf):
            # 递归处理 then 分支
            if stmt.then_body:
                # 找到 then_body 对应的 segment_id
                seg_id = self._find_segment_for_block(
                    info, stmt.then_body, parent_segment_id
                )
                self._analyze_units(stmt.then_body, info, seg_id, try_block_stack, loop_stack)
            # 递归处理 else 分支
            if stmt.else_body:
                seg_id = self._find_segment_for_block(
                    info, stmt.else_body, parent_segment_id
                )
                self._analyze_units(stmt.else_body, info, seg_id, try_block_stack, loop_stack)

        elif isinstance(stmt, (IRForRange, IRForEach, IRWhile)):
            # 确定循环类型
            loop_type = "for" if isinstance(stmt, (IRForRange, IRForEach)) else "while"
            new_loop_stack = loop_stack + [loop_type]
            
            # 递归处理循环体（使用新的 loop_stack）
            if stmt.body:
                seg_id = self._find_segment_for_block(
                    info, stmt.body, parent_segment_id
                )
                self._analyze_units(stmt.body, info, seg_id, try_block_stack, new_loop_stack)

    def _recurse_into_try_blocks_for_units(
        self,
        stmt: IRTryExcept,
        info: AsyncDataFlowInfo,
        parent_segment_id: Optional[int],
        try_block_stack: List[int],
        loop_stack: Optional[List[str]] = None,
    ) -> None:
        """递归进入 try 块进行 Unit 划分

        Args:
            stmt: try 块节点
            info: 数据流信息
            parent_segment_id: 父 Segment ID
            try_block_stack: 当前 try 块栈（try_block_id 列表）
            loop_stack: 当前循环栈（循环类型列表："for" 或 "while"）
        """
        if loop_stack is None:
            loop_stack = []
        
        # 递归处理 try 块
        if stmt.body:
            seg_id = self._find_segment_for_block(info, stmt.body, parent_segment_id)
            self._analyze_units(stmt.body, info, seg_id, try_block_stack, loop_stack)
        # 递归处理 except 处理器
        if stmt.handlers:
            for handler in stmt.handlers:
                if handler.body:
                    seg_id = self._find_segment_for_block(
                        info, handler.body, parent_segment_id
                    )
                    self._analyze_units(handler.body, info, seg_id, try_block_stack, loop_stack)
        # 递归处理 else 块
        if stmt.orelse:
            seg_id = self._find_segment_for_block(info, stmt.orelse, parent_segment_id)
            self._analyze_units(stmt.orelse, info, seg_id, try_block_stack, loop_stack)
        # 递归处理 finally 块
        if stmt.finalbody:
            seg_id = self._find_segment_for_block(
                info, stmt.finalbody, parent_segment_id
            )
            self._analyze_units(stmt.finalbody, info, seg_id, try_block_stack, loop_stack)

    def _find_segment_for_block(
        self, info: AsyncDataFlowInfo, block: IRNode, fallback_segment_id: Optional[int]
    ) -> Optional[int]:
        """查找语句块对应的 Segment ID

        Args:
            info: 数据流信息
            block: 语句块节点
            fallback_segment_id: 回退的 Segment ID

        Returns:
            Segment ID
        """
        # 查找第一个属于该语句块的 Segment
        # 使用 id() 比较对象身份，避免递归比较
        block_id = id(block)
        for segment in info.segments:
            if id(segment.statement_block_node) == block_id:
                return segment.segment_id
        # 如果没找到，使用回退值
        return fallback_segment_id

    def _collect_variables_defined_in_range(
        self,
        statements: List[IRNode],
        start_index: int,
        end_index: int,
        exclude_await_results: bool = False,
    ) -> List[str]:
        """收集指定范围内定义的变量

        注意：如果控制流语句（if/for/while）不包含 await，会递归进入其子语句块收集变量定义。
        这符合 Python 的作用域规则：if/else/for/while 不创建新作用域。

        Args:
            statements: 语句列表
            start_index: 开始索引（包含）
            end_index: 结束索引（不包含）
            exclude_await_results: 是否排除 await 结果变量

        Returns:
            变量名列表
        """
        variables = []
        for i in range(start_index, end_index):
            if i >= len(statements):
                break
            stmt = statements[i]
            if isinstance(stmt, IRAssign):
                # 检查是否是 await 赋值
                is_await_assign = isinstance(stmt.value, IRAwait)
                if exclude_await_results and is_await_assign:
                    continue

                # 获取目标变量
                target = stmt.get_target_expr()
                is_declaration = stmt.get_extension_param(
                    "is_variable_declaration", True
                )
                if isinstance(target, IRName) and is_declaration:
                    variables.append(target.id)

            # 如果是不包含 await 的控制流语句，递归进入子语句块收集变量定义
            # 因为在 Python 中，if/else/for/while 不创建新作用域
            elif isinstance(stmt, (IRIf, IRForRange, IRForEach, IRWhile, IRTryExcept)):
                if not self._node_contains_await(stmt):
                    # 递归收集子语句块中的变量定义
                    sub_vars = self._collect_variables_defined_in_node(
                        stmt, exclude_await_results
                    )
                    variables.extend(sub_vars)

        return variables

    def _collect_variables_defined_in_node(
        self, node: IRNode, exclude_await_results: bool = False
    ) -> List[str]:
        """递归收集节点中定义的所有变量

        Args:
            node: IR 节点
            exclude_await_results: 是否排除 await 结果变量

        Returns:
            变量名列表
        """
        variables = []

        # 如果是赋值语句
        if isinstance(node, IRAssign):
            is_await_assign = isinstance(node.value, IRAwait)
            if not (exclude_await_results and is_await_assign):
                target = node.get_target_expr()
                is_declaration = node.get_extension_param(
                    "is_variable_declaration", True
                )
                if isinstance(target, IRName) and is_declaration:
                    variables.append(target.id)

        # 如果是嵌套函数定义语句（def func(): ...）
        # 在 Python 中，函数定义等价于变量赋值：func = lambda: ...
        elif isinstance(node, IRFunctionNode):
            # 检查是否是嵌套函数（在另一个函数内部定义）
            parent = node.parent
            is_nested = False
            while parent:
                if isinstance(parent, IRFunctionNode):
                    is_nested = True
                    break
                parent = parent.parent

            if is_nested:
                # 嵌套函数定义等价于变量赋值，应该被识别为变量定义
                variables.append(node.name)

        # 如果是控制流语句，递归进入子语句块
        elif isinstance(node, IRIf):
            if node.then_body and isinstance(node.then_body, IRStmtBlock):
                for stmt in node.then_body.statements:
                    sub_vars = self._collect_variables_defined_in_node(
                        stmt, exclude_await_results
                    )
                    variables.extend(sub_vars)
            if node.else_body and isinstance(node.else_body, IRStmtBlock):
                for stmt in node.else_body.statements:
                    sub_vars = self._collect_variables_defined_in_node(
                        stmt, exclude_await_results
                    )
                    variables.extend(sub_vars)

        elif isinstance(node, (IRForRange, IRForEach, IRWhile)):
            body = getattr(node, "body", None)
            if body and isinstance(body, IRStmtBlock):
                for stmt in body.statements:
                    sub_vars = self._collect_variables_defined_in_node(
                        stmt, exclude_await_results
                    )
                    variables.extend(sub_vars)

        elif isinstance(node, IRTryExcept):
            # try 块
            if node.body and isinstance(node.body, IRStmtBlock):
                for stmt in node.body.statements:
                    sub_vars = self._collect_variables_defined_in_node(
                        stmt, exclude_await_results
                    )
                    variables.extend(sub_vars)
            # except 块
            for handler in node.handlers:
                handler_body = getattr(handler, "body", None)
                if handler_body and isinstance(handler_body, IRStmtBlock):
                    for stmt in handler_body.statements:
                        sub_vars = self._collect_variables_defined_in_node(
                            stmt, exclude_await_results
                        )
                        variables.extend(sub_vars)
            # finally 块
            if node.finalbody and isinstance(node.finalbody, IRStmtBlock):
                for stmt in node.finalbody.statements:
                    sub_vars = self._collect_variables_defined_in_node(
                        stmt, exclude_await_results
                    )
                    variables.extend(sub_vars)

        return variables

    def _analyze_variable_promotions(
        self, func_node: IRNode, info: AsyncDataFlowInfo
    ) -> None:
        """分析变量提升

        基于 Segment 父子关系判断变量是否跨 await：
        1. 变量在当前 Unit 定义和使用 → Local
        2. 变量不在当前 Unit 定义，查找所属 Segment
        3. 沿着 Segment 父链向上查找定义
        4. 检查从定义到使用之间是否跨越了其他 Unit（包含 await）
        5. 如果跨越 → Member，否则 → Header

        Args:
            func_node: 函数节点
            info: 数据流信息
        """
        if not isinstance(func_node, IRFunctionNode):
            return

        # 步骤1：构建变量定义和使用的映射
        var_def_unit_map = self._build_var_def_unit_map(info)
        var_use_units_map = self._build_var_use_units_map(func_node, info)

        # 步骤2：为每个变量应用提升规则
        all_vars = set(list(var_def_unit_map.keys()) + list(var_use_units_map.keys()))
        for var_name in all_vars:
            def_unit_id = var_def_unit_map.get(var_name)
            use_unit_ids = var_use_units_map.get(var_name, [])

            # 应用规则
            promotion_type, reason = self._determine_promotion_type(
                var_name, def_unit_id, use_unit_ids, info, func_node
            )

            # 记录提升信息
            self._record_promotion_info(
                var_name,
                def_unit_id,
                use_unit_ids,
                promotion_type,
                reason,
                info,
                func_node,
            )

            # 识别捕获变量和局部成员变量
            promotion_info = info.variable_promotions.get(var_name)
            if promotion_info:
                # 检查是否是捕获变量
                is_captured, captured_from = self._is_captured_variable(
                    var_name, func_node, info, promotion_info
                )
                promotion_info.is_captured_variable = is_captured
                promotion_info.captured_from_scope = captured_from

                # 检查是否是局部成员变量
                promotion_info.is_local_member = self._is_local_member_variable(
                    var_name, promotion_info, func_node
                )

    def _build_var_def_unit_map(
        self, info: AsyncDataFlowInfo
    ) -> Dict[str, Optional[int]]:
        """构建变量定义到 Unit ID 的映射

        Args:
            info: 数据流信息

        Returns:
            变量名 -> Unit ID 的映射
        """
        var_def_unit_map = {}

        for unit in info.units:
            for var_name in unit.variables_defined:
                # 记录第一次定义的 Unit
                if var_name not in var_def_unit_map:
                    var_def_unit_map[var_name] = unit.unit_id

        return var_def_unit_map

    def _build_var_use_units_map(
        self, func_node: IRNode, info: AsyncDataFlowInfo
    ) -> Dict[str, List[int]]:
        """构建变量使用到 Unit ID 列表的映射

        Args:
            func_node: 函数节点
            info: 数据流信息

        Returns:
            变量名 -> Unit ID 列表 的映射
        """
        var_use_units_map: Dict[str, List[int]] = {}
        # 先构建变量定义映射，用于判断赋值操作是定义还是使用
        var_def_unit_map = self._build_var_def_unit_map(info)

        # 遍历所有 Unit
        for unit in info.units:
            # 获取此 Unit 对应的语句
            statements = self._get_statements_for_unit(unit)

            # 收集此 Unit 中使用的变量
            # 对于不包含 await 的控制流语句，需要递归进入子语句块
            for stmt in statements:
                self._collect_var_uses_in_unit(
                    stmt,
                    unit.unit_id,
                    var_use_units_map,
                    info,
                    var_def_unit_map=var_def_unit_map,
                )

            # 检查紧跟在 Unit 之后的控制流语句的条件表达式
            # 这些条件表达式在进入子语句块之前执行，应该归入当前 Unit
            # 但是：如果当前 Unit 是 await Unit，则条件表达式不应该归入当前 Unit
            # 因为 await 结果变量在 await 完成后才可用，应该归入下一个 Unit
            statement_block = unit.statement_block_node
            if isinstance(statement_block, IRStmtBlock) and not unit.has_await:
                all_statements = statement_block.statements
                # 检查 Unit 结束位置的下一条语句
                next_stmt_idx = unit.end_stmt_index
                if next_stmt_idx < len(all_statements):
                    next_stmt = all_statements[next_stmt_idx]
                    # 如果是控制流语句，收集其条件表达式中的变量使用
                    if isinstance(next_stmt, IRIf):
                        self._collect_var_uses_non_recursive(
                            next_stmt.test, unit.unit_id, var_use_units_map
                        )
                    elif isinstance(next_stmt, IRWhile):
                        self._collect_var_uses_non_recursive(
                            next_stmt.test, unit.unit_id, var_use_units_map
                        )
                    elif isinstance(next_stmt, IRForRange):
                        self._collect_var_uses_non_recursive(
                            next_stmt.start, unit.unit_id, var_use_units_map
                        )
                        self._collect_var_uses_non_recursive(
                            next_stmt.end, unit.unit_id, var_use_units_map
                        )
                        if next_stmt.step:
                            self._collect_var_uses_non_recursive(
                                next_stmt.step, unit.unit_id, var_use_units_map
                            )
                    elif isinstance(next_stmt, IRForEach):
                        self._collect_var_uses_non_recursive(
                            next_stmt.iter_expr, unit.unit_id, var_use_units_map
                        )

        return var_use_units_map

    def _get_statements_for_unit(self, unit: Unit) -> List[IRNode]:
        """获取 Unit 对应的语句列表

        Args:
            unit: Unit 对象

        Returns:
            语句列表
        """
        statement_block = unit.statement_block_node
        statements = getattr(statement_block, "statements", [])
        return statements[unit.start_stmt_index : unit.end_stmt_index]

    def _collect_var_uses_in_unit(
        self,
        node: IRNode,
        unit_id: int,
        var_use_units_map: Dict[str, List[int]],
        info: AsyncDataFlowInfo,
        loop_local_vars: Optional[set] = None,
        var_def_unit_map: Optional[Dict[str, Optional[int]]] = None,
    ) -> None:
        """收集 Unit 中的变量使用（对于不包含 await 的控制流语句，递归进入子语句块）

        循环变量作用域规则：
        - for/while 循环变量的作用域限定在循环体内
        - 这些变量不会被收集到跨 Unit 的变量使用中
        - 如果用户需要在循环后使用，必须在循环前显式声明

        Args:
            node: IR 节点
            unit_id: 当前 Unit ID
            var_use_units_map: 变量使用映射
            info: 数据流信息
            loop_local_vars: 循环局部变量集合（用于排除）
            var_def_unit_map: 变量定义到 Unit ID 的映射（用于判断赋值是定义还是使用）
        """
        if loop_local_vars is None:
            loop_local_vars = set()
        if var_def_unit_map is None:
            var_def_unit_map = {}
        # 特殊处理 IRAssign：需要处理右侧的 value，也要处理左侧的 target（如果是表达式）
        if isinstance(node, IRAssign):
            # 检查是否是 await 赋值语句
            is_await_assign = isinstance(node.value, IRAwait)

            # 处理右侧的 value
            self._collect_var_uses_in_unit(
                node.value,
                unit_id,
                var_use_units_map,
                info,
                loop_local_vars,
                var_def_unit_map,
            )
            # 处理左侧的 target_exprs
            for target in node.target_exprs:
                if isinstance(target, IRName):
                    var_name = target.id
                    # 如果是 await 赋值语句，target 是 await 结果变量
                    # await 结果变量的定义属于下一个 Unit，不应该在当前 Unit 中识别为使用
                    if is_await_assign:
                        # await 结果变量，不收集为使用（定义在下一个 Unit）
                        continue
                    # 如果变量已经在之前的 Unit 中定义，则这是使用（赋值），不是定义
                    def_unit_id = var_def_unit_map.get(var_name)
                    if def_unit_id is not None and def_unit_id != unit_id:
                        # 变量已在之前的 Unit 中定义，这是使用
                        if var_name not in var_use_units_map:
                            var_use_units_map[var_name] = []
                        if unit_id not in var_use_units_map[var_name]:
                            var_use_units_map[var_name].append(unit_id)
                    # 否则，这是变量定义，不收集为使用
                    continue
                # 否则，递归处理 target 表达式中的变量使用
                # 例如：result[x] = value 中的 result[x]，需要收集 x 的使用
                self._collect_var_uses_in_unit(
                    target,
                    unit_id,
                    var_use_units_map,
                    info,
                    loop_local_vars,
                    var_def_unit_map,
                )
            return

        # 如果是控制流语句，检查是否包含 await
        if isinstance(node, (IRIf, IRForRange, IRForEach, IRWhile, IRTryExcept)):
            # 先处理条件/范围表达式
            if isinstance(node, IRIf):
                self._collect_var_uses_in_unit(
                    node.test, unit_id, var_use_units_map, info, loop_local_vars
                )
            elif isinstance(node, IRForRange):
                self._collect_var_uses_in_unit(
                    node.start,
                    unit_id,
                    var_use_units_map,
                    info,
                    loop_local_vars,
                    var_def_unit_map,
                )
                self._collect_var_uses_in_unit(
                    node.end,
                    unit_id,
                    var_use_units_map,
                    info,
                    loop_local_vars,
                    var_def_unit_map,
                )
                if node.step:
                    self._collect_var_uses_in_unit(
                        node.step,
                        unit_id,
                        var_use_units_map,
                        info,
                        loop_local_vars,
                        var_def_unit_map,
                    )
            elif isinstance(node, IRForEach):
                if node.iter_expr:
                    self._collect_var_uses_in_unit(
                        node.iter_expr,
                        unit_id,
                        var_use_units_map,
                        info,
                        loop_local_vars,
                        var_def_unit_map,
                    )
            elif isinstance(node, IRWhile):
                if node.test:
                    self._collect_var_uses_in_unit(
                        node.test,
                        unit_id,
                        var_use_units_map,
                        info,
                        loop_local_vars,
                        var_def_unit_map,
                    )

            # 检查控制流语句是否包含 await
            # 如果不包含 await，说明子语句块属于当前 Unit，需要递归收集变量使用
            contains_await = self._node_contains_await(node)
            if not contains_await:
                # 对于循环语句，创建新的循环局部变量集合
                # 循环变量的作用域限定在循环体内
                if isinstance(node, (IRForRange, IRForEach)):
                    # 获取循环变量名
                    loop_var_name = None
                    if isinstance(node, IRForRange) and isinstance(node.var, IRName):
                        loop_var_name = node.var.id
                    elif isinstance(node, IRForEach) and isinstance(node.var, IRName):
                        loop_var_name = node.var.id

                    # 创建新的循环局部变量集合（包含父循环的局部变量）
                    new_loop_local_vars = loop_local_vars.copy()
                    if loop_var_name:
                        new_loop_local_vars.add(loop_var_name)

                    # 递归处理循环体，使用新的循环局部变量集合
                    if node.body:
                        for stmt in node.body.statements:
                            self._collect_var_uses_in_unit(
                                stmt,
                                unit_id,
                                var_use_units_map,
                                info,
                                new_loop_local_vars,
                                var_def_unit_map,
                            )
                # 递归进入子语句块
                elif isinstance(node, IRIf):
                    if node.then_body:
                        for stmt in node.then_body.statements:
                            self._collect_var_uses_in_unit(
                                stmt,
                                unit_id,
                                var_use_units_map,
                                info,
                                loop_local_vars,
                                var_def_unit_map,
                            )
                    if node.else_body:
                        for stmt in node.else_body.statements:
                            self._collect_var_uses_in_unit(
                                stmt,
                                unit_id,
                                var_use_units_map,
                                info,
                                loop_local_vars,
                                var_def_unit_map,
                            )
                elif isinstance(node, IRWhile):
                    if node.body:
                        for stmt in node.body.statements:
                            self._collect_var_uses_in_unit(
                                stmt,
                                unit_id,
                                var_use_units_map,
                                info,
                                loop_local_vars,
                                var_def_unit_map,
                            )
                elif isinstance(node, IRTryExcept):
                    if node.body:
                        for stmt in node.body.statements:
                            self._collect_var_uses_in_unit(
                                stmt,
                                unit_id,
                                var_use_units_map,
                                info,
                                loop_local_vars,
                                var_def_unit_map,
                            )
                    for handler in node.handlers:
                        if handler.body:
                            for stmt in handler.body.statements:
                                self._collect_var_uses_in_unit(
                                    stmt,
                                    unit_id,
                                    var_use_units_map,
                                    info,
                                    loop_local_vars,
                                    var_def_unit_map,
                                )
                    if node.orelse:
                        for stmt in node.orelse.statements:
                            self._collect_var_uses_in_unit(
                                stmt,
                                unit_id,
                                var_use_units_map,
                                info,
                                loop_local_vars,
                                var_def_unit_map,
                            )
                    if node.finalbody:
                        for stmt in node.finalbody.statements:
                            self._collect_var_uses_in_unit(
                                stmt,
                                unit_id,
                                var_use_units_map,
                                info,
                                loop_local_vars,
                                var_def_unit_map,
                            )
            return

        # 如果是列表推导式，收集其循环变量到局部变量集合
        # 列表推导式创建自己的作用域，循环变量不应该被识别为外部作用域的变量
        if isinstance(node, IRListComp):
            # 收集列表推导式中所有生成器的循环变量
            comprehension_local_vars = loop_local_vars.copy()
            for generator in node.generators:
                if isinstance(generator, IRComprehension):
                    # 获取循环变量名
                    if isinstance(generator.target, IRName):
                        comprehension_local_vars.add(generator.target.id)
                    # 处理元组解包的情况
                    elif hasattr(generator.target, "elements"):
                        for element in getattr(generator.target, "elements"):
                            if isinstance(element, IRName):
                                comprehension_local_vars.add(element.id)

            # 递归处理列表推导式的子节点，使用新的局部变量集合
            for child in node.get_child_nodes():
                self._collect_var_uses_in_unit(
                    child,
                    unit_id,
                    var_use_units_map,
                    info,
                    comprehension_local_vars,
                    var_def_unit_map,
                )
            return

        # 如果是 IRName，记录变量使用
        # 排除循环局部变量（循环变量的作用域限定在循环体内）
        if isinstance(node, IRName):
            # 跳过函数调用的函数名
            if isinstance(node.parent, IRCall) and node.parent.func is node:
                # 这是函数调用的函数名，不是变量使用
                return

            # 检查是否是类型名称（不应该被识别为变量）
            if self._is_type_name(node):
                return

            var_name = node.id
            # 如果变量不在循环局部变量集合中，才记录其使用
            if var_name not in loop_local_vars:
                if var_name not in var_use_units_map:
                    var_use_units_map[var_name] = []
                if unit_id not in var_use_units_map[var_name]:
                    var_use_units_map[var_name].append(unit_id)

        # 递归处理子节点，但跳过控制流子语句块和列表推导式（已在上面处理）
        for child in node.get_child_nodes():
            if not isinstance(
                child,
                (
                    IRIf,
                    IRForRange,
                    IRForEach,
                    IRWhile,
                    IRTryExcept,
                    IRStmtBlock,
                    IRListComp,
                ),
            ):
                self._collect_var_uses_in_unit(
                    child,
                    unit_id,
                    var_use_units_map,
                    info,
                    loop_local_vars,
                    var_def_unit_map,
                )

    def _collect_var_uses_non_recursive(
        self, node: IRNode, unit_id: int, var_use_units_map: Dict[str, List[int]]
    ) -> None:
        """收集节点中的变量使用（不递归进入子语句块）

        Args:
            node: IR 节点
            unit_id: 当前 Unit ID
            var_use_units_map: 变量使用映射
        """
        # 特殊处理 IRAssign：只处理右侧的 value，不处理左侧的 target
        if isinstance(node, IRAssign):
            self._collect_var_uses_non_recursive(node.value, unit_id, var_use_units_map)
            return  # 不继续递归

        # 如果当前节点本身是控制流语句，只处理条件/范围表达式
        if isinstance(node, (IRIf, IRForRange, IRForEach, IRWhile, IRTryExcept)):
            if isinstance(node, IRIf):
                self._collect_var_uses_non_recursive(
                    node.test, unit_id, var_use_units_map
                )
            elif isinstance(node, (IRForRange, IRForEach)):
                # 处理循环变量和范围/迭代表达式
                if isinstance(node, IRForRange):
                    self._collect_var_uses_non_recursive(
                        node.start, unit_id, var_use_units_map
                    )
                    self._collect_var_uses_non_recursive(
                        node.end, unit_id, var_use_units_map
                    )
                    self._collect_var_uses_non_recursive(
                        node.step, unit_id, var_use_units_map
                    )
                elif isinstance(node, IRForEach):
                    self._collect_var_uses_non_recursive(
                        node.iter_expr, unit_id, var_use_units_map
                    )
            elif isinstance(node, IRWhile):
                # 只处理条件表达式
                self._collect_var_uses_non_recursive(
                    node.test, unit_id, var_use_units_map
                )
            # IRTryExcept 不需要处理任何表达式
            return  # 不继续递归

        # 如果是 IRName，记录变量使用
        if isinstance(node, IRName):
            # 需要检查父节点是否是 IRCall，并且当前 IRName 是 func 属性
            if isinstance(node.parent, IRCall) and node.parent.func is node:
                # 这是函数调用的函数名，不是变量使用
                return

            # 检查是否是类型名称（不应该被识别为变量）
            if self._is_type_name(node):
                return

            # 这是变量使用
            var_name = node.id
            if var_name not in var_use_units_map:
                var_use_units_map[var_name] = []
            if unit_id not in var_use_units_map[var_name]:
                var_use_units_map[var_name].append(unit_id)

        # 递归处理子节点，但跳过子语句块
        for child in node.get_child_nodes():
            # 跳过子语句块（它们有自己的 Unit）
            if isinstance(child, (IRIf, IRForRange, IRForEach, IRWhile, IRTryExcept)):
                # 对于控制流语句，只处理条件/范围表达式
                if isinstance(child, IRIf):
                    self._collect_var_uses_non_recursive(
                        child.test, unit_id, var_use_units_map
                    )
                elif isinstance(child, (IRForRange, IRForEach)):
                    if isinstance(child, IRForRange):
                        self._collect_var_uses_non_recursive(
                            child.start, unit_id, var_use_units_map
                        )
                        self._collect_var_uses_non_recursive(
                            child.end, unit_id, var_use_units_map
                        )
                        self._collect_var_uses_non_recursive(
                            child.step, unit_id, var_use_units_map
                        )
                    elif isinstance(child, IRForEach):
                        # 循环变量本身不算使用
                        if child.iter_expr:
                            self._collect_var_uses_non_recursive(
                                child.iter_expr, unit_id, var_use_units_map
                            )
                elif isinstance(child, IRWhile):
                    if child.test:
                        self._collect_var_uses_non_recursive(
                            child.test, unit_id, var_use_units_map
                        )
                elif isinstance(child, IRTryExcept):
                    # 不处理 body、handlers、finalbody
                    pass
            else:
                # 普通节点，继续递归
                self._collect_var_uses_non_recursive(child, unit_id, var_use_units_map)

    def _determine_promotion_type(
        self,
        var_name: str,
        def_unit_id: Optional[int],
        use_unit_ids: List[int],
        info: AsyncDataFlowInfo,
        func_node: IRNode,
    ) -> Tuple[str, str]:
        """确定变量的提升类型（基于 Segment 父链）

        规则：
        1. Local 变量：在同一 Unit 内定义和使用
        2. Member 变量：跨 await 使用（沿 Segment 父链查找，检查是否跨越包含 await 的 Unit）
        3. Header 变量：其他情况

        Args:
            var_name: 变量名
            def_unit_id: 定义所在的 Unit ID
            use_unit_ids: 使用所在的 Unit ID 列表
            info: 数据流信息
            func_node: 函数节点

        Returns:
            (promotion_type, reason) 元组
        """
        # 特殊情况：函数参数或闭包变量
        if def_unit_id is None:
            if isinstance(func_node, IRFunctionNode):
                # 先检查是否是全局变量（全局变量优先级高于闭包变量）
                if self._is_global_variable(var_name, func_node):
                    # 全局变量不应该被提升为 member，即使跨 await 也应该使用全局变量
                    if len(use_unit_ids) == 0:
                        return ("local", "未使用的全局变量")
                    # 全局变量跨 await 使用，但仍然使用全局变量，不是 member
                    return ("header", "全局变量跨 Unit 使用")

                # 然后检查是否是函数参数或闭包变量
                if self._is_function_parameter_or_closure(var_name, func_node):
                    return ("member", "函数参数或闭包变量")

            # 外部变量
            if len(use_unit_ids) == 0:
                return ("local", "未使用的外部变量")

            # 检查是否跨 await
            if self._external_var_crosses_await(use_unit_ids, info):
                return ("member", "外部变量跨 await 使用")

            return ("header", "外部变量跨 Unit 使用")

        # 规则1：Local 变量
        if len(use_unit_ids) == 0:
            return ("local", "定义但未使用")

        if len(use_unit_ids) == 1 and use_unit_ids[0] == def_unit_id:
            # 第一阶段：简单判断
            # 对于在同一 Unit 内定义和使用的变量，优先是 local
            # 除非变量在控制流条件中使用（需要 header 来保证 co_reenter 时可用）
            def_unit = self._find_unit_by_id(def_unit_id, info)
            if not def_unit:
                return ("local", "在同一 Unit 内定义和使用")

            # 检查变量是否在控制流条件中使用
            # 如果不在控制流条件中使用，直接返回 local
            # 但需要先检查下一个语句是否是包含 await 的控制流
            statement_block = def_unit.statement_block_node
            if isinstance(statement_block, IRStmtBlock):
                all_statements = statement_block.statements
                next_stmt_idx = def_unit.end_stmt_index
                if next_stmt_idx < len(all_statements):
                    next_stmt = all_statements[next_stmt_idx]
                    from mcpy.ir.statements.control import (
                        IRIf,
                        IRWhile,
                        IRForEach,
                        IRForRange,
                    )

                    # 先检查下一个语句是否是包含 await 的控制流
                    # 如果是，不应该返回 local，应该继续后续检查
                    if isinstance(next_stmt, (IRIf, IRWhile, IRForEach, IRForRange)):
                        has_await = self._unit_followed_by_control_flow_with_await(
                            def_unit_id, info
                        )
                        if has_await:
                            # 下一个语句是包含 await 的控制流，不应该返回 local，继续后续检查
                            # 跳过子 Segment 检查和后续的 local 判断，直接继续后续检查
                            pass
                        else:
                            # 下一个语句不包含 await，可以继续检查是否是 local
                            # 检查：如果该 Unit 在子 Segment 中（parent 不为 None）
                            # 说明变量在分支内部定义和使用，应该是 local
                            def_segment = None
                            for seg in info.segments:
                                if seg.segment_id == def_unit.segment_id:
                                    def_segment = seg
                                    break

                            if (
                                def_segment
                                and def_segment.parent_segment_id is not None
                            ):
                                # 在子 Segment 中，且下一个语句不包含 await，是 local
                                return ("local", "在同一 Unit 内定义和使用")

                            # 检查变量是否在控制流条件中使用
                            if isinstance(next_stmt, IRIf):
                                # 检查变量是否在 if 条件中使用
                                in_condition = self._var_used_in_expr(
                                    var_name, next_stmt.test
                                )
                                if not in_condition:
                                    # 不在 if 条件中使用，且下一个语句不包含 await，是 local
                                    return ("local", "在同一 Unit 内定义和使用")
                            elif isinstance(next_stmt, IRWhile):
                                # 检查变量是否在 while 条件中使用
                                in_condition = self._var_used_in_expr(
                                    var_name, next_stmt.test
                                )
                                if not in_condition:
                                    # 不在 while 条件中使用，且下一个语句不包含 await，是 local
                                    return ("local", "在同一 Unit 内定义和使用")
                            elif isinstance(next_stmt, IRForEach):
                                if not self._var_used_in_expr(
                                    var_name, next_stmt.iter_expr
                                ):
                                    # 不在 for 迭代表达式中使用，且下一个语句不包含 await，是 local
                                    return ("local", "在同一 Unit 内定义和使用")
                            elif isinstance(next_stmt, IRForRange):
                                # IRForRange 的条件检查，且下一个语句不包含 await，是 local
                                return ("local", "在同一 Unit 内定义和使用")
                    else:
                        # 没有下一条语句，检查是否在子 Segment 中
                        def_segment = None
                        for seg in info.segments:
                            if seg.segment_id == def_unit.segment_id:
                                def_segment = seg
                                break

                        if def_segment and def_segment.parent_segment_id is not None:
                            # 在子 Segment 中，是 local
                            return ("local", "在同一 Unit 内定义和使用")
                        else:
                            # 不在子 Segment 中，且没有下一条语句，是 local
                            return ("local", "在同一 Unit 内定义和使用")
                else:
                    # 没有下一条语句，检查是否在子 Segment 中
                    def_segment = None
                    for seg in info.segments:
                        if seg.segment_id == def_unit.segment_id:
                            def_segment = seg
                            break

                    if def_segment and def_segment.parent_segment_id is not None:
                        # 在子 Segment 中，是 local
                        return ("local", "在同一 Unit 内定义和使用")
                    else:
                        # 不在子 Segment 中，且没有下一条语句，是 local
                        return ("local", "在同一 Unit 内定义和使用")

            # 如果变量在控制流条件中使用，继续后续检查（可能是 header）
            pass

        # 规则1.5：检查 try 块内的变量是否在 except/finally 中使用
        # 如果变量在 try 块内定义，但在 except/finally 中使用，需要提升为 member
        if def_unit_id is not None:
            def_unit = self._find_unit_by_id(def_unit_id, info)
            if def_unit and def_unit.try_block_id is not None:
                # 变量在 try 块内定义，检查是否在 except/finally 中使用
                for use_unit_id in use_unit_ids:
                    use_unit = self._find_unit_by_id(use_unit_id, info)
                    if use_unit:
                        # 检查使用 Unit 是否在同一个 try 块的 except/finally 中
                        if self._is_var_used_in_except_or_finally(
                            var_name, def_unit, use_unit, info
                        ):
                            return (
                                "member",
                                "try 块内定义的变量在 except/finally 中使用",
                            )

        # 规则2：检查是否跨 await（基于 Segment 父链）
        crosses_await = self._crosses_await_via_segment_chain(
            def_unit_id, use_unit_ids, info
        )
        if crosses_await:
            return ("member", "跨 await 使用")

        # 规则3：Header 策略（第一阶段）
        # 变量跨 Unit 使用，但不跨 await
        # 先按原有逻辑判断为 header，然后在第二阶段应用严格检查
        header_reason = "跨 Unit 使用，但不跨 await"

        # 第二阶段：对 header 变量应用严格的安全检查
        # 检查变量是否满足严格的 header 安全条件
        is_safe = self._is_safe_header_variable(
            var_name, def_unit_id, use_unit_ids, info, func_node
        )
        if not is_safe:
            # 不满足严格条件，降级为 member
            return ("member", "不满足 header 安全条件，保守提升")

        return ("header", header_reason)

    def _is_safe_header_variable(
        self,
        var_name: str,
        def_unit_id: int,
        use_unit_ids: List[int],
        info: AsyncDataFlowInfo,
        func_node: IRNode,
    ) -> bool:
        """第二阶段：检查 header 变量是否满足严格的安全条件

        两条安全规则（满足任一即可）：

        规则1：pass-by-value 简单类型
        - int, bool, float, str 等简单类型可以安全地作为 header

        规则2：在所有子分支的第一个 Unit 的 await 之前都被重新赋值
        - TODO: 当前简化为检查是否在嵌套控制流中使用
        - 如果变量在嵌套的包含 await 的控制流中使用（如嵌套循环的迭代器），不安全

        Args:
            var_name: 变量名
            def_unit_id: 定义所在的 Unit ID
            use_unit_ids: 使用所在的 Unit ID 列表
            info: 数据流信息
            func_node: 函数节点

        Returns:
            是否满足严格的安全条件
        """
        # 获取定义所在的 Unit
        def_unit = self._find_unit_by_id(def_unit_id, info)
        if not def_unit:
            return False

        # 规则1：类型检查（pass-by-value 简单类型）
        # 从 func_node 中获取类型信息（因为此时 info.variable_promotions 可能还没有这个变量的信息）
        type_info = None
        symbol = None
        if isinstance(func_node, IRFunctionNode):
            symbol = func_node.lookup_symbol(var_name)
            if symbol and hasattr(symbol, "type_info"):
                type_info = symbol.type_info
            else:
                # 如果符号表中没有，尝试从定义节点获取
                if def_unit_id is not None:
                    ir_node = self._find_var_definition_node(
                        var_name, def_unit_id, info
                    )
                    if ir_node:
                        inferred_type = ir_node.get_extension_param("inferred_type")
                        if inferred_type:
                            type_info = inferred_type

        if type_info:
            # 使用 pass_by 字段判断是否是 pass-by-value 类型
            pass_by = type_info.pass_by
            # 如果 type_info.pass_by 是 None，尝试从 symbol.type_config 中获取
            if pass_by is None and symbol and hasattr(symbol, "type_config"):
                type_config = symbol.type_config
                if type_config and "pass_by" in type_config:
                    pass_by = type_config["pass_by"]
            # 如果还是 None，尝试从全局注册表中查找基础类型的配置
            if pass_by is None and type_info.name:
                from mcpy.symbol_registry import get_global_registry

                registry = get_global_registry()
                base_symbol = registry.lookup_type_symbol(type_info.name)
                if base_symbol and hasattr(base_symbol, "type_config"):
                    base_config = base_symbol.type_config
                    if base_config and "pass_by" in base_config:
                        pass_by = base_config["pass_by"]

            if pass_by == "value":
                # pass-by-value 类型，安全
                return True

        # 规则2：检查是否在所有子分支的第一个 Unit 的 await 之前都被重新赋值
        # 找到定义 Unit 的下一条语句（如果是控制流语句）
        statement_block = def_unit.statement_block_node
        if not isinstance(statement_block, IRStmtBlock):
            # 没有下一条语句，默认安全
            return True

        all_statements = statement_block.statements
        next_stmt_idx = def_unit.end_stmt_index
        if next_stmt_idx >= len(all_statements):
            # 没有下一条语句，默认安全
            return True

        next_stmt = all_statements[next_stmt_idx]
        from mcpy.ir.statements.control import IRIf, IRWhile, IRForEach, IRForRange

        if isinstance(next_stmt, IRIf):
            # if 语句：检查 then_body 和 else_body 两个分支
            branches = []
            if next_stmt.then_body:
                branches.append(next_stmt.then_body)
            if next_stmt.else_body:
                branches.append(next_stmt.else_body)

            # 对于每个分支，检查是否满足规则2
            for branch_body in branches:
                if not self._check_var_reassigned_before_first_await(
                    var_name, branch_body, def_unit_id, info
                ):
                    # 某个分支不满足，不安全
                    return False

            # 所有分支都满足，安全
            return True

        elif isinstance(next_stmt, (IRWhile, IRForEach, IRForRange)):
            # 循环语句：检查 body
            if next_stmt.body:
                if not self._check_var_reassigned_before_first_await(
                    var_name, next_stmt.body, def_unit_id, info
                ):
                    # 循环体不满足，不安全
                    return False

            # 循环体满足，安全
            return True

        # 其他情况（没有控制流语句），默认安全
        return True

    def _check_var_reassigned_before_first_await(
        self,
        var_name: str,
        control_flow_body: IRNode,
        def_unit_id: int,
        info: AsyncDataFlowInfo,
    ) -> bool:
        """检查变量在控制流语句体的第一个 await 之前是否被重新赋值

        Args:
            var_name: 变量名
            control_flow_body: 控制流语句体（IRStmtBlock）
            def_unit_id: 定义所在的 Unit ID
            info: 数据流信息

        Returns:
            如果变量在第一个 await 之前被重新赋值，返回 True
            如果没有 await，返回 True（默认安全）
        """
        if not isinstance(control_flow_body, IRStmtBlock):
            return True

        # 找到控制流语句体中的第一个包含 await 的 Unit
        first_await_unit = self._find_first_await_unit_in_block(control_flow_body, info)
        if first_await_unit is None:
            # 没有 await，默认安全
            return True

        # 检查在第一个 await Unit 之前，变量是否被重新赋值
        # 需要检查所有在 first_await_unit 之前的 Units
        for unit in info.units:
            # 检查 Unit 是否在控制流语句体内部
            if not self._is_unit_in_block(unit, control_flow_body):
                continue

            # 检查 Unit 是否在 first_await_unit 之前
            if unit.unit_id >= first_await_unit.unit_id:
                continue

            # 检查变量是否在这个 Unit 中被重新赋值
            if self._is_var_reassigned_in_unit(var_name, unit):
                return True

        # 在第一个 await 之前没有被重新赋值，不安全
        return False

    def _find_first_await_unit_in_block(
        self, block: IRNode, info: AsyncDataFlowInfo
    ) -> Optional[Unit]:
        """找到语句块中的第一个包含 await 的 Unit

        Args:
            block: 语句块节点（IRStmtBlock）
            info: 数据流信息

        Returns:
            第一个包含 await 的 Unit，如果没有则返回 None
        """
        if not isinstance(block, IRStmtBlock):
            return None

        block_id = id(block)
        first_await_unit = None

        for unit in info.units:
            # 检查 Unit 是否在 block 内部
            if not self._is_unit_in_block(unit, block):
                continue

            # 检查 Unit 是否包含 await
            if unit.has_await:
                # 找到第一个包含 await 的 Unit（按 unit_id 排序）
                if first_await_unit is None or unit.unit_id < first_await_unit.unit_id:
                    first_await_unit = unit

        return first_await_unit

    def _is_unit_in_block(self, unit: Unit, block: IRNode) -> bool:
        """检查 Unit 是否在语句块内部（包括嵌套）

        Args:
            unit: Unit 对象
            block: 语句块节点（IRStmtBlock）

        Returns:
            如果 Unit 在 block 内部则返回 True
        """
        if not isinstance(block, IRStmtBlock):
            return False

        block_id = id(block)
        current = unit.statement_block_node

        # 沿着 parent 链向上查找
        while current is not None:
            if id(current) == block_id:
                return True
            # 向上查找 parent
            if hasattr(current, "parent"):
                current = current.parent
            else:
                break

        return False

    def _is_var_reassigned_in_unit(self, var_name: str, unit: Unit) -> bool:
        """检查变量是否在 Unit 中被重新赋值

        Args:
            var_name: 变量名
            unit: Unit 对象

        Returns:
            如果变量在 Unit 中被重新赋值则返回 True
        """
        statements = self._get_statements_for_unit(unit)
        for stmt in statements:
            if isinstance(stmt, IRAssign):
                target = stmt.get_target_expr()
                if isinstance(target, IRName) and target.id == var_name:
                    # 找到变量赋值
                    return True
        return False

    def _descendants_have_await(self, segment_id: int, info: AsyncDataFlowInfo) -> bool:
        """检查 Segment 的后代 Segments 是否包含 await

        Args:
            segment_id: Segment ID
            info: 数据流信息

        Returns:
            如果后代 Segments 包含 await 则返回 True
        """
        # 查找所有后代 Segments 中的 Units
        for unit in info.units:
            # 只检查后代 Segments，不检查当前 Segment
            if unit.segment_id != segment_id and self._is_descendant_segment(
                unit.segment_id, segment_id, info
            ):
                if unit.has_await:
                    return True
        return False

    def _is_descendant_segment(
        self, descendant_id: int, ancestor_id: int, info: AsyncDataFlowInfo
    ) -> bool:
        """检查一个 Segment 是否是另一个 Segment 的后代

        Args:
            descendant_id: 潜在后代 Segment ID
            ancestor_id: 潜在祖先 Segment ID
            info: 数据流信息

        Returns:
            如果 descendant_id 是 ancestor_id 的后代则返回 True
        """
        # 从 descendant 开始，沿着父链向上查找
        for segment in info.segments:
            if segment.segment_id == descendant_id:
                # 沿着父链向上查找
                current_segment = segment
                while current_segment:
                    if current_segment.segment_id == ancestor_id:
                        return True
                    # 查找父 Segment
                    if current_segment.parent_segment_id is None:
                        break
                    parent_segment = None
                    for seg in info.segments:
                        if seg.segment_id == current_segment.parent_segment_id:
                            parent_segment = seg
                            break
                    current_segment = parent_segment
                break
        return False

    def _is_used_in_control_flow_condition(
        self, var_name: str, def_unit_id: int, info: AsyncDataFlowInfo
    ) -> bool:
        """检查变量是否在控制流条件中使用

        Args:
            var_name: 变量名
            def_unit_id: 定义所在的 Unit ID
            info: 数据流信息

        Returns:
            如果变量在控制流条件中使用则返回 True
        """
        def_unit = self._find_unit_by_id(def_unit_id, info)
        if not def_unit:
            return False

        # 获取 Unit 所属的语句块
        statement_block = def_unit.statement_block_node
        if not isinstance(statement_block, IRStmtBlock):
            return False

        all_statements = statement_block.statements
        # 检查 Unit 结束位置的下一条语句
        next_stmt_idx = def_unit.end_stmt_index
        if next_stmt_idx >= len(all_statements):
            return False

        next_stmt = all_statements[next_stmt_idx]
        # 检查是否是控制流语句
        from mcpy.ir.statements.control import IRIf, IRWhile, IRForEach, IRForRange

        if isinstance(next_stmt, IRIf):
            # 检查变量是否在 if 条件中使用
            if self._var_used_in_expr(var_name, next_stmt.test):
                return True
        elif isinstance(next_stmt, IRWhile):
            # 检查变量是否在 while 条件中使用
            if self._var_used_in_expr(var_name, next_stmt.test):
                return True
        elif isinstance(next_stmt, IRForEach):
            # 检查变量是否在 for 迭代表达式中使用
            if self._var_used_in_expr(var_name, next_stmt.iter_expr):
                return True
        elif isinstance(next_stmt, IRForRange):
            # IRForRange 没有条件表达式，不需要检查
            pass

        return False

    def _var_used_in_expr(self, var_name: str, expr, visited=None) -> bool:
        """检查变量是否在表达式中使用

        注意：只检查表达式树本身，不通过 parent 关系访问其他节点
        """
        if expr is None:
            return False

        # 避免循环引用
        if visited is None:
            visited = set()

        node_id = id(expr)
        if node_id in visited:
            return False
        visited.add(node_id)

        from mcpy.ir.expressions.basic import IRName

        # 递归检查表达式树
        if isinstance(expr, IRName) and expr.id == var_name:
            return True

        # 递归检查子节点
        # 只检查表达式相关的属性，跳过 parent、statements 等结构属性
        if hasattr(expr, "__dict__"):
            skip_attrs = {
                "parent",
                "statements",
                "body",
                "then_body",
                "else_body",
                "test",
            }
            for attr_name, attr_value in expr.__dict__.items():
                if attr_name in skip_attrs:
                    continue
                if isinstance(attr_value, list):
                    for item in attr_value:
                        if self._var_used_in_expr(var_name, item, visited):
                            return True
                elif hasattr(attr_value, "__class__") and not isinstance(
                    attr_value, (str, int, float, bool, type(None))
                ):
                    if self._var_used_in_expr(var_name, attr_value, visited):
                        return True

        return False

    def _unit_followed_by_control_flow_with_await(
        self, unit_id: int, info: AsyncDataFlowInfo
    ) -> bool:
        """检查 Unit 之后是否紧跟着包含 await 的控制流语句

        Args:
            unit_id: Unit ID
            info: 数据流信息

        Returns:
            bool: 是否紧跟着包含 await 的控制流语句
        """
        from mcpy.ir.statements.control import (
            IRIf,
            IRWhile,
            IRForEach,
            IRForRange,
        )

        # 找到这个 Unit
        unit = self._find_unit_by_id(unit_id, info)
        if not unit:
            return False

        # 获取 Unit 所属的语句块
        statement_block = unit.statement_block_node
        if not isinstance(statement_block, IRStmtBlock):
            return False

        all_statements = statement_block.statements
        # 检查 Unit 结束位置的下一条语句
        next_stmt_idx = unit.end_stmt_index
        if next_stmt_idx >= len(all_statements):
            return False

        next_stmt = all_statements[next_stmt_idx]
        # 如果不是控制流语句，返回 False
        if not isinstance(next_stmt, (IRIf, IRForRange, IRForEach, IRWhile)):
            return False

        # 检查这个控制流语句本身是否包含 await
        # 需要检查控制流语句体内部的 Units 是否有 await

        # 获取控制流语句的语句体
        control_flow_body = None
        if isinstance(next_stmt, IRIf):
            # if 语句：检查 then_body 和 else_body
            # 如果 then_body 或 else_body 包含 await，返回 True
            if hasattr(next_stmt, "then_body") and next_stmt.then_body:
                control_flow_body = next_stmt.then_body
            elif hasattr(next_stmt, "else_body") and next_stmt.else_body:
                control_flow_body = next_stmt.else_body
        elif isinstance(next_stmt, (IRWhile, IRForEach, IRForRange)):
            # 循环语句：检查 body
            if hasattr(next_stmt, "body") and next_stmt.body:
                control_flow_body = next_stmt.body

        if control_flow_body:
            # 查找控制流语句体内部的 Units（包括嵌套的控制流语句体内部的 Units）
            # 通过检查 Unit 的 statement_block_node 是否是 control_flow_body 的后代
            control_flow_body_id = id(control_flow_body)
            for inner_unit in info.units:
                # 检查 Unit 的 statement_block_node 是否是 control_flow_body 的后代
                # 通过检查 parent 链
                current = inner_unit.statement_block_node
                while current is not None:
                    if id(current) == control_flow_body_id:
                        # 这个 Unit 在控制流语句体内部（包括嵌套）
                        if inner_unit.has_await:
                            return True
                        break
                    # 向上查找 parent
                    if hasattr(current, "parent"):
                        current = current.parent
                    else:
                        break

        return False

    def _is_function_parameter_or_closure(
        self, var_name: str, func_node: IRNode
    ) -> bool:
        """检查变量是否是函数参数或闭包变量

        Args:
            var_name: 变量名
            func_node: 函数节点

        Returns:
            bool: 是否是函数参数或闭包变量
        """
        if not isinstance(func_node, IRFunctionNode):
            return False

        # 检查函数参数
        for param in func_node.params:
            if param.name == var_name:
                return True

        # 检查闭包变量
        captured_vars = getattr(func_node, "captured_vars", None) or []
        if var_name in captured_vars:
            return True

        closure_vars = getattr(func_node, "closure_vars", None) or []
        if var_name in closure_vars:
            return True

        return False

    def _external_var_crosses_await(
        self, use_unit_ids: List[int], info: AsyncDataFlowInfo
    ) -> bool:
        """检查外部变量是否跨 await 使用

        Args:
            use_unit_ids: 使用所在的 Unit ID 列表
            info: 数据流信息

        Returns:
            bool: 是否跨 await
        """
        if len(use_unit_ids) == 0:
            return False

        # 检查所有使用所在的 Segment 是否包含 await
        # 外部变量（如循环变量）可能在循环体内使用，循环体中有 await
        for use_unit_id in use_unit_ids:
            unit = self._find_unit_by_id(use_unit_id, info)
            if not unit:
                continue

            # 查找 Unit 所属的 Segment
            segment = self._find_segment_by_id(unit.segment_id, info)
            if segment and segment.has_await:
                return True

        # 如果多个 Unit 使用，检查它们之间是否有 await
        if len(use_unit_ids) > 1:
            return self._has_await_between_units(use_unit_ids, info)

        return False

    def _crosses_await_via_segment_chain(
        self, def_unit_id: int, use_unit_ids: List[int], info: AsyncDataFlowInfo
    ) -> bool:
        """基于 Segment 父链检查是否跨 await

        关键规则：
        1. await 一定在 Unit 的最后，所以当前 Unit 内的变量使用一定在 await 之前
        2. await 结果变量属于下一个 Unit
        3. 不能简单按 Unit ID 大小判断，应该根据 Segment 父子关系找到路径

        Args:
            def_unit_id: 定义所在的 Unit ID
            use_unit_ids: 使用所在的 Unit ID 列表
            info: 数据流信息

        Returns:
            bool: 是否跨 await
        """
        # 获取定义 Unit
        def_unit = self._find_unit_by_id(def_unit_id, info)
        if not def_unit:
            return False

        for use_unit_id in use_unit_ids:
            if use_unit_id == def_unit_id:
                continue  # 同一 Unit，不跨 await

            use_unit = self._find_unit_by_id(use_unit_id, info)
            if not use_unit:
                continue

            # 检查从 def_unit 到 use_unit 的路径上是否有 await
            if self._has_await_on_path(def_unit, use_unit, info):
                return True

        return False

    def _has_await_on_path(
        self, def_unit: Unit, use_unit: Unit, info: AsyncDataFlowInfo
    ) -> bool:
        """检查从 def_unit 到 use_unit 的路径上是否有 await

        策略：
        1. 如果两个 Unit 在同一个 Segment，检查它们之间的 Unit 是否有 await
        2. 如果在不同 Segment，需要通过 Segment 父链找到公共祖先，检查路径上是否有 await

        Args:
            def_unit: 定义所在的 Unit
            use_unit: 使用所在的 Unit
            info: 数据流信息

        Returns:
            bool: 是否有 await
        """
        # 情况1：同一个 Segment
        if def_unit.segment_id == use_unit.segment_id:
            # 检查两个 Unit 之间（不包括它们自己）是否有 await
            # 注意：await 在 Unit 的最后，所以 def_unit 的 await 不算，use_unit 的 await 也不算
            min_id = min(def_unit.unit_id, use_unit.unit_id)
            max_id = max(def_unit.unit_id, use_unit.unit_id)

            for unit in info.units:
                # 检查中间的 Unit（不包括 def_unit 和 use_unit）
                if min_id < unit.unit_id < max_id and unit.has_await:
                    return True

            # 如果 def_unit 在前且有 await，则跨 await
            if def_unit.unit_id < use_unit.unit_id and def_unit.has_await:
                return True

            return False

        # 情况2：不同 Segment，需要通过 Segment 父链判断
        # 获取两个 Segment
        def_segment = self._find_segment_by_id(def_unit.segment_id, info)
        use_segment = self._find_segment_by_id(use_unit.segment_id, info)

        if not def_segment or not use_segment:
            return False

        # 找到从 def_segment 到 use_segment 的路径
        # 简化实现：检查是否有一个是另一个的祖先
        # 如果 use_segment 是 def_segment 的子孙，检查路径上是否有 await
        if self._is_ancestor_segment(
            def_segment.segment_id, use_segment.segment_id, info
        ):
            # def_segment 是 use_segment 的祖先
            # 需要检查从 def_unit 到 use_segment 的路径上是否有 await

            # 1. 检查 def_unit 本身是否有 await
            if def_unit.has_await:
                return True

            # 2. 检查 def_segment 中 def_unit 之后的 Unit 是否有 await
            for unit in info.units:
                if (
                    unit.segment_id == def_unit.segment_id
                    and unit.unit_id > def_unit.unit_id
                    and unit.has_await
                ):
                    return True

            # 3. 检查从 def_segment 到 use_segment 路径上的所有子 Segment 中的 Unit
            # 收集路径上的所有 Segment（不包括 use_segment 本身）
            path_segments = []
            current_id = use_segment.parent_segment_id  # 从 use_segment 的父节点开始
            while current_id is not None and current_id != def_segment.segment_id:
                seg = self._find_segment_by_id(current_id, info)
                if not seg:
                    break
                path_segments.append(current_id)
                current_id = seg.parent_segment_id

            # 检查这些 Segment 中的 Unit 是否有 await
            for seg_id in path_segments:
                for unit in info.units:
                    if unit.segment_id == seg_id and unit.has_await:
                        return True

            # 检查 use_segment 中 use_unit 之前的 Unit 是否有 await
            # 注意：use_unit 本身的 await 不算（变量使用在 await 之前）
            for unit in info.units:
                if (
                    unit.segment_id == use_unit.segment_id
                    and unit.unit_id < use_unit.unit_id
                    and unit.has_await
                ):
                    return True

            # 特殊情况：如果 use_segment 是循环体，且 use_unit 有 await
            # 即使变量使用在 await 之前，但由于循环会重复执行，
            # 变量会在 await 之后的下一次迭代中再次被使用，所以算跨 await
            if use_unit.has_await and self._is_loop_body_segment(use_segment):
                return True

            return False

        # 如果 def_segment 是 use_segment 的子孙，一定跨 await（因为要回到父层）
        if self._is_ancestor_segment(
            use_segment.segment_id, def_segment.segment_id, info
        ):
            return True

        # 其他情况：两个 Segment 是兄弟或堂兄弟关系
        # 找到公共祖先，检查路径上是否有 await
        return self._has_await_between_segments(def_segment, use_segment, info)

    def _find_segment_by_id(
        self, segment_id: int, info: AsyncDataFlowInfo
    ) -> Optional[Segment]:
        """根据 ID 查找 Segment"""
        for segment in info.segments:
            if segment.segment_id == segment_id:
                return segment
        return None

    def _is_ancestor_segment(
        self, ancestor_id: int, descendant_id: int, info: AsyncDataFlowInfo
    ) -> bool:
        """检查 ancestor_id 是否是 descendant_id 的祖先"""
        current_id = descendant_id
        visited = set()

        while current_id is not None and current_id not in visited:
            if current_id == ancestor_id:
                return True
            visited.add(current_id)

            # 找到当前 Segment 的父 Segment
            segment = self._find_segment_by_id(current_id, info)
            if not segment:
                break
            current_id = segment.parent_segment_id

        return False

    def _is_loop_body_segment(self, segment: Segment) -> bool:
        """检查 Segment 是否是循环体

        Args:
            segment: Segment 对象

        Returns:
            bool: 是否是循环体
        """
        # 检查 statement_block 的 parent 是否是循环语句
        if not hasattr(segment.statement_block_node, "parent"):
            return False

        parent = segment.statement_block_node.parent
        return isinstance(parent, (IRWhile, IRForRange, IRForEach))

    def _has_await_between_segments(
        self, seg1: Segment, seg2: Segment, info: AsyncDataFlowInfo
    ) -> bool:
        """检查两个 Segment 之间是否有 await（通过公共祖先）"""
        # 简化实现：如果它们有公共祖先且不是直接父子关系，则认为跨 await
        # 这个逻辑可能需要更精细的实现
        return True

    def _has_await_between_units(
        self, unit_ids: List[int], info: AsyncDataFlowInfo
    ) -> bool:
        """检查多个 Unit 之间是否有 await

        检查从 unit_ids[0] 到 unit_ids[-1] 之间（包括它们自己）是否有任何 Unit 包含 await

        Args:
            unit_ids: Unit ID 列表
            info: 数据流信息

        Returns:
            bool: 是否有 await
        """
        if len(unit_ids) < 2:
            return False

        # 获取 Unit ID 的范围
        min_id = min(unit_ids)
        max_id = max(unit_ids)

        # 检查这个范围内的所有 Unit 是否有 await
        for unit in info.units:
            if min_id <= unit.unit_id <= max_id and unit.has_await:
                return True

        return False

    def _find_unit_by_id(self, unit_id: int, info: AsyncDataFlowInfo) -> Optional[Unit]:
        """根据 ID 查找 Unit

        Args:
            unit_id: Unit ID
            info: 数据流信息

        Returns:
            Unit 对象，如果未找到返回 None
        """
        for unit in info.units:
            if unit.unit_id == unit_id:
                return unit
        return None

    def _is_var_used_in_except_or_finally(
        self,
        var_name: str,
        def_unit: Unit,
        use_unit: Unit,
        info: AsyncDataFlowInfo,
    ) -> bool:
        """检查变量是否在 except/finally 中使用

        如果变量在 try 块内定义，但在 except/finally 中使用，需要提升为 member。

        Args:
            var_name: 变量名
            def_unit: 定义所在的 Unit
            use_unit: 使用所在的 Unit
            info: 数据流信息

        Returns:
            bool: 如果变量在 except/finally 中使用，返回 True
        """
        # 检查定义 Unit 是否在 try 块内
        if def_unit.try_block_id is None:
            return False

        # 检查使用 Unit 是否在同一个 try 块的 except/finally 中
        if use_unit.try_block_id != def_unit.try_block_id:
            # 不在同一个 try 块，不需要特殊处理
            return False

        # 找到对应的 try 块信息
        try_block_info = None
        for tb_info in info.try_blocks:
            if tb_info.try_block_id == def_unit.try_block_id:
                try_block_info = tb_info
                break

        if not try_block_info:
            return False

        try_node = try_block_info.try_node

        # 检查定义 Unit 是否在 try 块的 body 中
        def_in_try_body = False
        if try_node.body:
            def_statements = getattr(def_unit.statement_block_node, "statements", [])
            try_body_statements = getattr(try_node.body, "statements", [])
            # 检查定义 Unit 的语句块是否是 try 块的 body
            if id(def_unit.statement_block_node) == id(try_node.body):
                def_in_try_body = True
            # 或者检查定义 Unit 的语句是否在 try 块的 body 中
            elif isinstance(try_node.body, IRStmtBlock):
                for stmt in try_body_statements:
                    if self._node_contains_statement(
                        def_unit.statement_block_node, stmt
                    ):
                        def_in_try_body = True
                        break

        if not def_in_try_body:
            return False

        # 检查使用 Unit 是否在 except 或 finally 中
        use_in_except_or_finally = False

        # 检查 except 处理器
        if try_node.handlers:
            for handler in try_node.handlers:
                if handler.body:
                    if id(use_unit.statement_block_node) == id(handler.body):
                        use_in_except_or_finally = True
                        break
                    elif isinstance(handler.body, IRStmtBlock):
                        handler_statements = getattr(handler.body, "statements", [])
                        for stmt in handler_statements:
                            if self._node_contains_statement(
                                use_unit.statement_block_node, stmt
                            ):
                                use_in_except_or_finally = True
                                break
                        if use_in_except_or_finally:
                            break

        # 检查 finally 块
        if not use_in_except_or_finally and try_node.finalbody:
            if id(use_unit.statement_block_node) == id(try_node.finalbody):
                use_in_except_or_finally = True
            elif isinstance(try_node.finalbody, IRStmtBlock):
                finalbody_statements = getattr(try_node.finalbody, "statements", [])
                for stmt in finalbody_statements:
                    if self._node_contains_statement(
                        use_unit.statement_block_node, stmt
                    ):
                        use_in_except_or_finally = True
                        break

        return use_in_except_or_finally

    def _node_contains_statement(self, container: IRNode, stmt: IRNode) -> bool:
        """检查容器节点是否包含指定的语句节点

        Args:
            container: 容器节点
            stmt: 语句节点

        Returns:
            bool: 如果容器包含语句，返回 True
        """
        if not isinstance(container, IRStmtBlock):
            return False

        statements = getattr(container, "statements", [])
        return stmt in statements

    def _find_var_definition_node(
        self, var_name: str, def_unit_id: int, info: AsyncDataFlowInfo
    ) -> Optional[IRNode]:
        """查找变量定义的 IR 节点

        Args:
            var_name: 变量名
            def_unit_id: 定义所在的 Unit ID
            info: 数据流信息

        Returns:
            IR 节点（通常是 IRAssign 的 target），如果未找到返回 None
        """
        # 找到定义所在的 Unit
        def_unit = self._find_unit_by_id(def_unit_id, info)
        if not def_unit:
            return None

        # 获取 Unit 对应的语句列表
        statements = self._get_statements_for_unit(def_unit)

        # 查找变量定义的赋值语句
        for stmt in statements:
            if isinstance(stmt, IRAssign):
                target = stmt.get_target_expr()
                if isinstance(target, IRName) and target.id == var_name:
                    return target  # 返回 IRName 节点

        return None

    def _find_var_init_expr(
        self, var_name: str, def_unit_id: int, info: AsyncDataFlowInfo
    ) -> Optional[IRNode]:
        """查找变量的初始化表达式（用于 Protocol 类型的 decltype）

        Args:
            var_name: 变量名
            def_unit_id: 定义所在的 Unit ID
            info: 数据流信息

        Returns:
            初始化表达式 IR 节点（IRAssign 的 value），如果未找到返回 None
        """
        # 找到定义所在的 Unit
        def_unit = self._find_unit_by_id(def_unit_id, info)
        if not def_unit:
            return None

        # 获取 Unit 对应的语句列表
        statements = self._get_statements_for_unit(def_unit)

        # 查找变量定义的赋值语句
        for stmt in statements:
            if isinstance(stmt, IRAssign):
                target = stmt.get_target_expr()
                if isinstance(target, IRName) and target.id == var_name:
                    return stmt.value  # 返回赋值的右侧表达式

        return None

    def _record_promotion_info(
        self,
        var_name: str,
        def_unit_id: Optional[int],
        use_unit_ids: List[int],
        promotion_type: str,
        reason: str,
        info: AsyncDataFlowInfo,
        func_node: Optional[IRNode] = None,
    ) -> None:
        """记录变量提升信息

        Args:
            var_name: 变量名
            def_unit_id: 定义 Unit ID
            use_unit_ids: 使用 Unit ID 列表
            promotion_type: 提升类型
            reason: 提升原因
            info: 数据流信息
            func_node: 函数节点（用于查找符号）
        """
        # 获取定义和使用所在的 Segment ID
        def_segment_id = None
        if def_unit_id is not None:
            def_unit = self._find_unit_by_id(def_unit_id, info)
            if def_unit:
                def_segment_id = def_unit.segment_id

        use_segment_ids = []
        for use_unit_id in use_unit_ids:
            use_unit = self._find_unit_by_id(use_unit_id, info)
            if use_unit and use_unit.segment_id not in use_segment_ids:
                use_segment_ids.append(use_unit.segment_id)

        # 查找变量的 IR 节点、符号和类型信息
        ir_node = None
        symbol = None
        type_info = None

        if func_node:
            if isinstance(func_node, IRFunctionNode):
                # 从符号表查找符号和类型信息（对所有变量都尝试）
                symbol = func_node.lookup_symbol(var_name)
                if symbol and hasattr(symbol, "type_info"):
                    type_info = symbol.type_info

            # 如果有定义 Unit，尝试查找变量定义的 IR 节点
            if def_unit_id is not None:
                ir_node = self._find_var_definition_node(var_name, def_unit_id, info)
                # 如果符号表中没有类型信息，尝试从定义节点获取
                if not type_info and ir_node:
                    # 从 IR 节点的 inferred_type 获取类型信息
                    inferred_type = ir_node.get_extension_param("inferred_type")
                    if inferred_type:
                        type_info = inferred_type
            else:
                # 即使没有定义 Unit，也尝试从符号表查找 IR 节点
                # 这对于在 Pass 中创建的临时变量（如 __await_temp_0）很重要
                if not ir_node and symbol and hasattr(symbol, "ir_node"):
                    ir_node = symbol.ir_node
                    # 如果符号表中没有类型信息，尝试从 IR 节点获取
                    if not type_info and ir_node:
                        inferred_type = ir_node.get_extension_param("inferred_type")
                        if inferred_type:
                            type_info = inferred_type

        # 查找变量的初始化表达式（用于 Protocol 类型的 decltype）
        init_expr = None
        if def_unit_id is not None:
            init_expr = self._find_var_init_expr(var_name, def_unit_id, info)

        # 记录提升信息（新字段将在 _analyze_variable_promotions 中设置）
        promotion_info = VariablePromotionInfo(
            variable_name=var_name,
            promotion_type=promotion_type,
            reason=reason,
            defined_in_unit_id=def_unit_id,
            defined_in_segment_id=def_segment_id,
            used_in_unit_ids=use_unit_ids,
            used_in_segment_ids=use_segment_ids,
            ir_node=ir_node,
            symbol=symbol,
            type_info=type_info,
            init_expr=init_expr,
            is_captured_variable=False,  # 将在 _analyze_variable_promotions 中设置
            is_local_member=False,  # 将在 _analyze_variable_promotions 中设置
            captured_from_scope=None,  # 将在 _analyze_variable_promotions 中设置
        )
        info.variable_promotions[var_name] = promotion_info

        # 更新分类列表（向后兼容）
        if promotion_type == "member":
            # 检查是否是简单嵌套函数（无捕获），如果是则不加入 member_variables
            is_simple_nested_function = False
            if symbol and hasattr(symbol, "ir_node") and symbol.ir_node:
                if isinstance(symbol.ir_node, IRFunctionNode):
                    # 检查是否是简单函数（无捕获）
                    is_simple = symbol.ir_node.get_extension_param(
                        "is_simple_non_capturing", False
                    )
                    if not is_simple:
                        # 如果标记未设置，检查 captured_vars 是否为空
                        captured_vars = getattr(symbol.ir_node, "captured_vars", None)
                        is_simple = not captured_vars or len(captured_vars) == 0
                    is_simple_nested_function = is_simple

            # 简单嵌套函数不加入 member_variables，它们将在调用处通过临时对象调用
            if not is_simple_nested_function:
                if var_name not in info.member_variables:
                    info.member_variables.append(var_name)
        elif promotion_type == "header":
            # 检查是否是全局变量，全局变量不应该添加到 header_variables
            # 因为全局变量应该直接使用，不需要在函数开头声明
            is_global = isinstance(
                func_node, IRFunctionNode
            ) and self._is_global_variable(var_name, func_node)

            if not is_global:
                if var_name not in info.header_variables:
                    info.header_variables.append(var_name)
        else:  # "local"
            if def_unit_id is not None:
                if def_unit_id not in info.local_variables:
                    info.local_variables[def_unit_id] = []
                if var_name not in info.local_variables[def_unit_id]:
                    info.local_variables[def_unit_id].append(var_name)

    def _is_descendant_of(self, node: IRNode, ancestor: IRNode) -> bool:
        """判断 node 是否是 ancestor 的后代节点

        Args:
            node: 要检查的节点
            ancestor: 祖先节点

        Returns:
            bool: node 是否是 ancestor 的后代
        """
        current = node
        while current:
            if current == ancestor:
                return True
            if hasattr(current, "parent"):
                current = current.parent
            else:
                break
        return False

    def _is_global_variable(self, var_name: str, func_node: IRFunctionNode) -> bool:
        """检查变量是否是全局变量

        检查方式：
        1. 首先检查函数节点的 global_vars 扩展参数（显式声明的 global 变量）
        2. 如果不在 global_vars 中，检查符号表判断变量是否在模块级别定义

        这样可以正确处理只读取全局变量而不需要 global 声明的情况。

        Args:
            var_name: 变量名
            func_node: 函数节点

        Returns:
            bool: 是否是全局变量
        """

        # 方式1：检查显式声明的 global 变量
        global_vars = func_node.get_extension_param("global_vars") or set()
        if var_name in global_vars:
            return True

        # 方式2：检查符号表，判断变量是否在模块级别定义
        # 查找变量符号
        symbol = func_node.lookup_symbol(var_name, symbol_kinds=[SymbolKind.VARIABLE])
        if not symbol or symbol.kind != SymbolKind.VARIABLE:
            return False

        # 检查符号的定义节点是否在模块级别（不在函数作用域内）
        if not symbol.ir_node:
            return False

        # 获取模块节点
        ir_module = func_node.get_ir_module()
        if not ir_module:
            return False

        # 检查符号的定义节点是否在模块级别（不在任何函数作用域内）
        # 如果符号的 ir_node 不在当前函数的作用域内，且不在任何函数作用域内，则是模块级变量
        def_node = symbol.ir_node

        # 检查定义节点是否在模块级别（不在任何函数作用域内）
        current = def_node.parent
        while current:
            if isinstance(current, IRFunctionNode):
                # 定义在某个函数内，不是模块级变量
                return False
            if current == ir_module:
                # 到达模块级别，是模块级变量
                return True
            current = current.parent

        # 如果找不到模块节点，但符号存在且不在当前函数内，可能是模块级变量
        # 为了安全，检查定义节点是否在当前函数的作用域内
        if self._is_descendant_of(def_node, func_node):
            # 在当前函数内定义，不是全局变量
            return False

        # 定义不在当前函数内，且不在任何函数内，可能是模块级变量
        # 但为了更准确，我们还需要确认它确实在模块级别
        # 如果符号的 ir_node 的父节点是模块，则是模块级变量
        if def_node.parent == ir_module:
            return True

        return False

    def _find_outer_function(
        self, func_node: IRFunctionNode
    ) -> Optional[IRFunctionNode]:
        """查找外层函数

        Args:
            func_node: 当前函数节点

        Returns:
            外层函数节点，如果没有则返回 None
        """
        current = func_node.parent
        while current:
            if isinstance(current, IRFunctionNode):
                return current
            if hasattr(current, "parent"):
                current = current.parent
            else:
                break
        return None

    def _is_captured_variable(
        self,
        var_name: str,
        func_node: IRFunctionNode,
        info: AsyncDataFlowInfo,
        promotion_info: VariablePromotionInfo,
    ) -> tuple[bool, Optional[str]]:
        """判断变量是否是捕获的闭包变量

        Args:
            var_name: 变量名
            func_node: 当前函数节点
            info: 数据流信息
            promotion_info: 变量提升信息

        Returns:
            (is_captured, outer_func_name): 是否是捕获变量，以及捕获自哪个函数
        """
        # 先检查是否是全局变量（全局变量不是捕获变量）
        if self._is_global_variable(var_name, func_node):
            return False, None

        # 如果变量在当前函数内定义，不是捕获变量
        if promotion_info.defined_in_unit_id is not None:
            # 检查定义节点是否在当前函数的作用域内
            if promotion_info.ir_node:
                if self._is_descendant_of(promotion_info.ir_node, func_node):
                    # 在当前函数内定义，不是捕获变量
                    return False, None

        # 查找变量的符号
        symbol = func_node.lookup_symbol(var_name)
        if not symbol or not symbol.ir_node:
            return False, None

        # 检查定义节点是否在当前函数的作用域内
        if self._is_descendant_of(symbol.ir_node, func_node):
            # 在当前函数内定义，不是捕获变量
            return False, None

        # 定义节点不在当前函数内，是捕获变量
        # 查找外层函数
        outer_func = self._find_outer_function(func_node)
        outer_func_name = outer_func.name if outer_func else None

        return True, outer_func_name

    def _is_local_member_variable(
        self,
        var_name: str,
        promotion_info: VariablePromotionInfo,
        func_node: IRFunctionNode,
    ) -> bool:
        """判断变量是否是局部成员变量（在函数内部定义，跨 await 使用）

        Args:
            var_name: 变量名
            promotion_info: 变量提升信息
            func_node: 函数节点

        Returns:
            bool: 是否是局部成员变量
        """
        # 必须在函数内部定义
        if promotion_info.defined_in_unit_id is None:
            return False

        # 必须是 member 类型（跨 await 使用）
        if promotion_info.promotion_type != "member":
            return False

        # 检查定义节点是否在当前函数内
        if promotion_info.ir_node:
            if self._is_descendant_of(promotion_info.ir_node, func_node):
                return True

        return False

    def _validate_and_supplement_captured_vars(
        self, func_node: IRFunctionNode, info: AsyncDataFlowInfo
    ) -> None:
        """验证并补充 captured_vars，确保包含所有捕获变量

        在数据流分析完成后调用，确保 captured_vars 包含所有标记为捕获变量的变量

        Args:
            func_node: 函数节点
            info: 数据流信息
        """
        if not hasattr(func_node, "captured_vars"):
            func_node.captured_vars = []

        captured_vars_set = set(func_node.captured_vars)
        missing_captured_vars = []

        # 检查所有标记为捕获变量的变量
        for var_name, promotion_info in info.variable_promotions.items():
            if promotion_info.is_captured_variable:
                if var_name not in captured_vars_set:
                    # 补充到 captured_vars
                    missing_captured_vars.append(var_name)
                    func_node.captured_vars.append(var_name)
                    captured_vars_set.add(var_name)

        # 如果补充了变量，记录警告（用于调试）
        if missing_captured_vars:
            import warnings

            warnings.warn(
                f"Function {func_node.name}: Added missing captured variables to captured_vars: {missing_captured_vars}"
            )
